From dabcced9200676c2e269612b7c5fd8f899831faf Mon Sep 17 00:00:00 2001 From: Andrzej Pomirski Date: Fri, 27 Mar 2026 01:35:26 +0100 Subject: [PATCH 1/7] Add @sensor and @setting descriptors to all remaining integrations Adds introspectable interface decorators to 44 integration files that previously lacked them, bringing descriptor coverage from ~12 to ~56 integrations. This enables downstream consumers like Home Assistant to automatically discover available sensors, settings, and their metadata (icons, units, device classes) without hardcoding per-device knowledge. Addresses #1617 --- .../airdog/airpurifier/airpurifier_airdog.py | 21 +++ .../cgllc/airmonitor/airqualitymonitor.py | 17 +++ .../airmonitor/airqualitymonitor_miot.py | 40 +++++- .../chuangmi/camera/chuangmi_camera.py | 14 ++ .../chuangmi/plug/chuangmi_plug.py | 7 + miio/integrations/chunmi/cooker/cooker.py | 119 +++++++++++------ .../deerma/humidifier/airhumidifier_jsqs.py | 18 +++ .../deerma/humidifier/airhumidifier_mjjsq.py | 25 ++++ .../dmaker/airfresh/airfresh_t2017.py | 31 +++++ miio/integrations/dmaker/fan/fan.py | 30 +++++ miio/integrations/dmaker/fan/fan_miot.py | 34 +++++ .../dreame/vacuum/dreamevacuum_miot.py | 81 +++++++----- miio/integrations/huayi/light/huizuo.py | 26 ++++ .../ksmb/walkingpad/walkingpad.py | 35 +++++ miio/integrations/leshow/fan/fan_leshow.py | 31 +++++ .../acpartner/airconditioningcompanion.py | 17 +++ .../acpartner/airconditioningcompanionMCN.py | 8 ++ miio/integrations/lumi/camera/aqaracamera.py | 19 +++ .../lumi/curtain/curtain_youpin.py | 30 +++++ miio/integrations/mijia/vacuum/g1vacuum.py | 60 ++++++--- .../mmgg/petwaterdispenser/status.py | 25 ++++ .../nwt/dehumidifier/airdehumidifier.py | 21 +++ miio/integrations/philips/light/ceil.py | 37 ++++++ .../philips/light/philips_bulb.py | 7 + .../philips/light/philips_eyecare.py | 31 +++++ .../philips/light/philips_moonlight.py | 32 +++++ .../philips/light/philips_rwread.py | 35 +++++ miio/integrations/pwzn/relay/pwzn_relay.py | 4 + .../roidmi/vacuum/roidmivacuum_miot.py | 120 ++++++++++++------ .../shuii/humidifier/airhumidifier_jsq.py | 23 ++++ .../tinymu/toiletlid/toiletlid.py | 7 + .../viomi/viomidishwasher/viomidishwasher.py | 18 +++ .../aircondition/airconditioner_miot.py | 79 ++++++++---- .../xiaomi/repeater/wifirepeater.py | 6 + .../xiaomi/wifispeaker/wifispeaker.py | 13 +- .../dual_switch/yeelight_dual_switch.py | 28 ++++ .../yunmi/waterpurifier/waterpurifier.py | 19 +++ .../waterpurifier/waterpurifier_yunmi.py | 76 +++++++---- .../zhimi/airpurifier/airfresh.py | 52 +++++--- .../zhimi/airpurifier/airpurifier.py | 78 +++++++----- miio/integrations/zhimi/fan/zhimi_miot.py | 55 +++++--- miio/integrations/zhimi/heater/heater.py | 24 ++++ miio/integrations/zhimi/heater/heater_miot.py | 23 ++++ miio/integrations/zimi/clock/alarmclock.py | 8 +- 44 files changed, 1233 insertions(+), 251 deletions(-) diff --git a/miio/integrations/airdog/airpurifier/airpurifier_airdog.py b/miio/integrations/airdog/airpurifier/airpurifier_airdog.py index ab6f19395..5fa3479f7 100644 --- a/miio/integrations/airdog/airpurifier/airpurifier_airdog.py +++ b/miio/integrations/airdog/airpurifier/airpurifier_airdog.py @@ -7,6 +7,7 @@ from miio import Device, DeviceStatus from miio.click_common import EnumType, command, format_output +from miio.devicestatus import sensor, setting _LOGGER = logging.getLogger(__name__) @@ -48,16 +49,24 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property + @sensor("Power", icon="mdi:power") def power(self) -> str: """Power state.""" return self.data["power"] @property + @sensor("Is On", icon="mdi:power") def is_on(self) -> bool: """True if device is turned on.""" return self.power == "on" @property + @setting( + "Mode", + setter_name="set_mode_and_speed", + icon="mdi:fan", + choices=OperationMode, + ) def mode(self) -> OperationMode: """Operation mode. @@ -66,26 +75,38 @@ def mode(self) -> OperationMode: return OperationMode(self.data["mode"]) @property + @setting( + "Speed", + setter_name="set_mode_and_speed", + icon="mdi:speedometer", + min_value=1, + max_value=5, + step=1, + ) def speed(self) -> int: """Current speed level.""" return self.data["speed"] @property + @setting("Child Lock", setter_name="set_child_lock", icon="mdi:lock") def child_lock(self) -> bool: """Return True if child lock is on.""" return self.data["lock"] == "lock" @property + @sensor("Clean Filters", icon="mdi:air-filter") def clean_filters(self) -> bool: """True if the display shows "-C-" and the filter must be cleaned.""" return self.data["clean"] == "y" @property + @sensor("PM2.5", unit="μg/m³", icon="mdi:blur", device_class="pm25") def pm25(self) -> int: """Return particulate matter value (0...300μg/m³).""" return self.data["pm"] @property + @sensor("Formaldehyde", icon="mdi:chemical-weapon") def hcho(self) -> int | None: """Return formaldehyde value.""" if self.data["hcho"] is not None: diff --git a/miio/integrations/cgllc/airmonitor/airqualitymonitor.py b/miio/integrations/cgllc/airmonitor/airqualitymonitor.py index 1d26bb794..30d55c8aa 100644 --- a/miio/integrations/cgllc/airmonitor/airqualitymonitor.py +++ b/miio/integrations/cgllc/airmonitor/airqualitymonitor.py @@ -5,6 +5,7 @@ from miio.click_common import command, format_output from miio.device import Device, DeviceStatus +from miio.devicestatus import sensor, setting _LOGGER = logging.getLogger(__name__) @@ -57,16 +58,19 @@ def __init__(self, data): self.data = data @property + @sensor("Power", icon="mdi:power") def power(self) -> str | None: """Current power state.""" return self.data.get("power") @property + @sensor("Is On", icon="mdi:power") def is_on(self) -> bool: """Return True if the device is turned on.""" return self.power == "on" @property + @sensor("USB Power", icon="mdi:usb") def usb_power(self) -> bool | None: """Return True if the device's usb is on.""" if "usb_state" in self.data and self.data["usb_state"] is not None: @@ -74,16 +78,19 @@ def usb_power(self) -> bool | None: return None @property + @sensor("AQI", icon="mdi:air-filter") def aqi(self) -> int | None: """Air quality index value (0..600).""" return self.data.get("aqi") @property + @sensor("Battery", unit="%", device_class="battery", icon="mdi:battery") def battery(self) -> int | None: """Current battery level (0..100).""" return self.data.get("battery") @property + @setting("Display Clock", setter_name="set_display_clock", icon="mdi:clock-outline") def display_clock(self) -> bool | None: """Display a clock instead the AQI.""" if "time_state" in self.data and self.data["time_state"] is not None: @@ -91,6 +98,7 @@ def display_clock(self) -> bool | None: return None @property + @setting("Night Mode", setter_name="set_night_mode", icon="mdi:weather-night") def night_mode(self) -> bool | None: """Return True if the night mode is on.""" if "night_state" in self.data and self.data["night_state"] is not None: @@ -98,46 +106,55 @@ def night_mode(self) -> bool | None: return None @property + @sensor("Night Time Begin", icon="mdi:clock-start") def night_time_begin(self) -> str | None: """Return the begin of the night time.""" return self.data.get("night_beg_time") @property + @sensor("Night Time End", icon="mdi:clock-end") def night_time_end(self) -> str | None: """Return the end of the night time.""" return self.data.get("night_end_time") @property + @sensor("Sensor State", icon="mdi:eye") def sensor_state(self) -> str | None: """Sensor state.""" return self.data.get("sensor_state") @property + @sensor( def co2(self) -> int | None: """Return co2 value (400...9999ppm).""" return self.data.get("co2") @property + @sensor( def co2e(self) -> int | None: """Return co2e value (400...9999ppm).""" return self.data.get("co2e") @property + @sensor("Humidity", unit="%", device_class="humidity", icon="mdi:water-percent") def humidity(self) -> float | None: """Return humidity value (0...100%).""" return self.data.get("humidity") @property + @sensor("PM2.5", unit="μg/m³", device_class="pm25", icon="mdi:blur") def pm25(self) -> float | None: """Return pm2.5 value (0...999μg/m³).""" return self.data.get("pm25") @property + @sensor("Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") def temperature(self) -> float | None: """Return temperature value (-10...50°C).""" return self.data.get("temperature") @property + @sensor("TVOC", icon="mdi:cloud") def tvoc(self) -> int | None: """Return tvoc value.""" return self.data.get("tvoc") diff --git a/miio/integrations/cgllc/airmonitor/airqualitymonitor_miot.py b/miio/integrations/cgllc/airmonitor/airqualitymonitor_miot.py index 676f0ae15..796eca026 100644 --- a/miio/integrations/cgllc/airmonitor/airqualitymonitor_miot.py +++ b/miio/integrations/cgllc/airmonitor/airqualitymonitor_miot.py @@ -4,6 +4,7 @@ import click from miio.click_common import command, format_output +from miio.devicestatus import sensor, setting from miio.miot_device import DeviceStatus, MiotDevice _LOGGER = logging.getLogger(__name__) @@ -107,57 +108,94 @@ def __init__(self, data): self.data = data @property + @sensor("Humidity", unit="%", icon="mdi:water-percent", device_class="humidity") def humidity(self) -> int: """Return humidity value (0...100%).""" return self.data["humidity"] @property + @sensor("PM2.5", unit="µg/m³", icon="mdi:blur") def pm25(self) -> int: """Return PM 2.5 value (0...1000ppm).""" return self.data["pm25"] @property + @sensor("PM10", unit="µg/m³", icon="mdi:blur-linear") def pm10(self) -> int: """Return PM 10 value (0...1000ppm).""" return self.data["pm10"] @property + @sensor("Temperature", unit="°C", icon="mdi:thermometer", device_class="temperature") def temperature(self) -> float: """Return temperature value (-30...100°C).""" return self.data["temperature"] @property + @sensor("CO2", unit="ppm", icon="mdi:molecule-co2", device_class="carbon_dioxide") def co2(self) -> int: """Return co2 value (0...9999ppm).""" return self.data["co2"] @property + @sensor("Battery", unit="%", icon="mdi:battery", device_class="battery") def battery(self) -> int: """Return battery level (0...100%).""" return self.data["battery"] @property + @sensor("Charging State", icon="mdi:battery-charging") def charging_state(self) -> ChargingState: """Return charging state.""" return ChargingState(self.data["charging_state"]) @property + @setting( + "Monitoring Frequency", + unit="s", + setter_name="set_monitoring_frequency_duration", + min_value=0, + max_value=600, + icon="mdi:update", + ) def monitoring_frequency(self) -> int: """Return monitoring frequency time (0..600 s).""" return self.data["monitoring_frequency"] @property + @setting( + "Screen Off", + unit="s", + setter_name="set_screen_off_duration", + min_value=0, + max_value=300, + icon="mdi:monitor-off", + ) def screen_off(self) -> int: """Return screen off time (0..300 s).""" return self.data["screen_off"] @property + @setting( + "Device Off", + unit="min", + setter_name="set_device_off_duration", + min_value=0, + max_value=60, + icon="mdi:power-off", + ) def device_off(self) -> int: """Return device off time (0..60 min).""" return self.data["device_off"] @property - def display_temperature_unit(self): + @setting( + "Display Temperature Unit", + setter_name="set_display_temperature_unit", + choices=DisplayTemperatureUnitCGDN1, + icon="mdi:temperature-celsius", + ) + def display_temperature_unit(self) -> DisplayTemperatureUnitCGDN1: """Return display temperature unit.""" return DisplayTemperatureUnitCGDN1(self.data["temperature_unit"]) diff --git a/miio/integrations/chuangmi/camera/chuangmi_camera.py b/miio/integrations/chuangmi/camera/chuangmi_camera.py index dac1b4744..f314e48c3 100644 --- a/miio/integrations/chuangmi/camera/chuangmi_camera.py +++ b/miio/integrations/chuangmi/camera/chuangmi_camera.py @@ -11,6 +11,7 @@ from miio.click_common import EnumType, command, format_output from miio.device import Device, DeviceStatus +from miio.devicestatus import sensor, setting _LOGGER = logging.getLogger(__name__) @@ -91,66 +92,79 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property + @setting(name="Power", setter_name="on", icon="mdi:power") def power(self) -> bool: """Camera power.""" return self.data["power"] == "on" @property + @setting(name="Motion Record", setter_name="motion_record_on", icon="mdi:motion-sensor") def motion_record(self) -> bool: """Motion record status.""" return self.data["motion_record"] == "on" @property + @setting(name="Light", setter_name="light_on", icon="mdi:lightbulb") def light(self) -> bool: """Camera light status.""" return self.data["light"] == "on" @property + @setting(name="Full Color", setter_name="full_color_on", icon="mdi:palette") def full_color(self) -> bool: """Full color with bad lighting conditions.""" return self.data["full_color"] == "on" @property + @setting(name="Flip", setter_name="flip_on", icon="mdi:flip-vertical") def flip(self) -> bool: """Image 180 degrees flip status.""" return self.data["flip"] == "on" @property + @setting(name="Improve Program", setter_name="improve_program_on", icon="mdi:chart-line") def improve_program(self) -> bool: """Customer experience improvement program status.""" return self.data["improve_program"] == "on" @property + @setting(name="WDR", setter_name="wdr_on", icon="mdi:contrast-box") def wdr(self) -> bool: """Wide dynamic range status.""" return self.data["wdr"] == "on" @property + @sensor(name="Track", icon="mdi:crosshairs-gps") def track(self) -> bool: """Tracking status.""" return self.data["track"] == "on" @property + @setting(name="Watermark", setter_name="watermark_on", icon="mdi:watermark") def watermark(self) -> bool: """Apply watermark to video.""" return self.data["watermark"] == "on" @property + @sensor(name="SD Card Status", icon="mdi:sd") def sdcard_status(self) -> int: """SD card status.""" return self.data["sdcard_status"] @property + @sensor(name="Max Client", icon="mdi:account-multiple") def max_client(self) -> int: """Unknown.""" return self.data["max_client"] @property + @sensor(name="Night Mode", icon="mdi:weather-night") def night_mode(self) -> int: """Night mode.""" return self.data["night_mode"] @property + @sensor(name="Mini Level", icon="mdi:volume-low") def mini_level(self) -> int: """Unknown.""" return self.data["mini_level"] diff --git a/miio/integrations/chuangmi/plug/chuangmi_plug.py b/miio/integrations/chuangmi/plug/chuangmi_plug.py index 3429e6acf..2425f1d0d 100644 --- a/miio/integrations/chuangmi/plug/chuangmi_plug.py +++ b/miio/integrations/chuangmi/plug/chuangmi_plug.py @@ -6,6 +6,7 @@ from miio import Device, DeviceException, DeviceStatus from miio.click_common import command, format_output +from miio.devicestatus import sensor, setting from miio.utils import deprecated _LOGGER = logging.getLogger(__name__) @@ -45,6 +46,7 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property + @sensor("Power", icon="mdi:power-plug") def power(self) -> bool: """Current power state.""" if "on" in self.data: @@ -55,15 +57,18 @@ def power(self) -> bool: raise DeviceException("There was neither 'on' or 'power' in data") @property + @setting("Power", setter_name="on", icon="mdi:power-plug") def is_on(self) -> bool: """True if device is on.""" return self.power @property + @sensor("Temperature", unit="°C", icon="mdi:thermometer", device_class="temperature") def temperature(self) -> int: return self.data["temperature"] @property + @setting("USB Power", setter_name="usb_on", icon="mdi:usb") def usb_power(self) -> bool | None: """True if USB is on.""" if "usb_on" in self.data and self.data["usb_on"] is not None: @@ -71,6 +76,7 @@ def usb_power(self) -> bool | None: return None @property + @sensor("Load Power", unit="W", icon="mdi:flash", device_class="power") def load_power(self) -> float | None: """Current power load, if available.""" if "load_power" in self.data and self.data["load_power"] is not None: @@ -84,6 +90,7 @@ def wifi_led(self) -> bool | None: return self.led @property + @setting("LED", setter_name="set_led", icon="mdi:led-on") def led(self) -> bool | None: """True if the wifi led is turned on.""" if "wifi_led" in self.data and self.data["wifi_led"] is not None: diff --git a/miio/integrations/chunmi/cooker/cooker.py b/miio/integrations/chunmi/cooker/cooker.py index 1131a259c..64b6b7ad2 100644 --- a/miio/integrations/chunmi/cooker/cooker.py +++ b/miio/integrations/chunmi/cooker/cooker.py @@ -8,6 +8,7 @@ from miio.click_common import command, format_output from miio.device import Device, DeviceStatus +from miio.devicestatus import sensor _LOGGER = logging.getLogger(__name__) @@ -123,12 +124,14 @@ def __init__(self, data: str): self.data = [int(data[i : i + 2], 16) for i in range(0, len(data), 2)] else: self.data = [] - @property + + @sensor("Temperatures", unit="°C", icon="mdi:thermometer") def temperatures(self) -> list[int]: return self.data - @property + + @sensor("Raw", icon="mdi:code-string") def raw(self) -> str: return "".join([f"{value:02x}" for value in self.data]) @@ -162,28 +165,34 @@ def __init__(self, custom: str): Octet 11-16 (01 00 00 00 1d 1f): Meaning unknown """ self.custom = [int(custom[i : i + 2], 16) for i in range(0, len(custom), 2)] - @property + + @sensor("Jingzhu Appointment", icon="mdi:clock-outline") def jingzhu_appointment(self) -> time: return time(hour=self.custom[0], minute=self.custom[1]) - @property + + @sensor("Kuaizhu Appointment", icon="mdi:clock-outline") def kuaizhu_appointment(self) -> time: return time(hour=self.custom[2], minute=self.custom[3]) - @property + + @sensor("Zhuzhou Appointment", icon="mdi:clock-outline") def zhuzhou_appointment(self) -> time: return time(hour=self.custom[4], minute=self.custom[5]) - @property + + @sensor("Zhuzhou Cooking", icon="mdi:clock-outline") def zhuzhou_cooking(self) -> time: return time(hour=self.custom[6], minute=self.custom[7]) - @property + + @sensor("Favorite Appointment", icon="mdi:clock-outline") def favorite_appointment(self) -> time: return time(hour=self.custom[8], minute=self.custom[9]) - @property + + @sensor("Favorite Cooking", icon="mdi:clock-outline") def favorite_cooking(self) -> time: return time(hour=self.custom[10], minute=self.custom[11]) @@ -205,8 +214,9 @@ def __init__(self, stage: str): Octet 5 (ff): Meaning unknown. """ self.stage = stage - @property + + @sensor("State", icon="mdi:pot-steam") def state(self) -> int: """ @@ -215,38 +225,44 @@ def state(self) -> int: 12: Cooking finished """ return int(self.stage[0:2], 16) - @property + + @sensor("Rice ID", icon="mdi:rice") def rice_id(self) -> int: return int(self.stage[2:6], 16) - @property + + @sensor("Taste", icon="mdi:food-variant") def taste(self) -> int: return int(self.stage[6:8], 16) - @property + + @sensor("Taste Phase", icon="mdi:food-variant") def taste_phase(self) -> int: phase = int(self.taste / 33) if phase > 2: return 2 return phase - @property + + @sensor("Name", icon="mdi:label") def name(self) -> str: try: return COOKING_STAGES[self.state]["name"] except KeyError: return "Unknown stage" - @property + + @sensor("Description", icon="mdi:text") def description(self) -> str: try: return COOKING_STAGES[self.state]["description"] except KeyError: return "" - @property + + @sensor("Raw", icon="mdi:code-string") def raw(self) -> str: return self.stage @@ -267,24 +283,27 @@ def __init__(self, timeouts: str | None = None): self.timeouts = [ int(timeouts[i : i + 2], 16) for i in range(0, len(timeouts), 2) ] - @property + + @sensor("LED Off Timeout", unit="s", icon="mdi:led-off") def led_off(self) -> int: return self.timeouts[0] @led_off.setter def led_off(self, delay: int): self.timeouts[0] = delay - @property + + @sensor("Lid Open Timeout", unit="s", icon="mdi:pot-steam-outline") def lid_open(self) -> int: return self.timeouts[1] @lid_open.setter def lid_open(self, timeout: int): self.timeouts[1] = timeout - @property + + @sensor("Lid Open Warning Timeout", unit="s", icon="mdi:alert") def lid_open_warning(self) -> int: return self.timeouts[2] @@ -322,8 +341,9 @@ def __init__(self, settings: str | None = None): self._settings = [ int(settings[i : i + 2], 16) for i in range(0, len(settings), 2) ] - @property + + @sensor("Pressure Supported", icon="mdi:gauge") def pressure_supported(self) -> bool: return self._settings[0] & 1 != 0 @@ -333,8 +353,9 @@ def pressure_supported(self, supported: bool): self._settings[0] |= 1 else: self._settings[0] &= 254 - @property + + @sensor("LED On", icon="mdi:led-on") def led_on(self) -> bool: return self._settings[0] & 2 != 0 @@ -344,8 +365,9 @@ def led_on(self, on: bool): self._settings[0] |= 2 else: self._settings[0] &= 253 - @property + + @sensor("Auto Keep Warm", icon="mdi:pot-steam") def auto_keep_warm(self) -> bool: return self._settings[0] & 4 != 0 @@ -355,8 +377,9 @@ def auto_keep_warm(self, keep_warm: bool): self._settings[0] |= 4 else: self._settings[0] &= 251 - @property + + @sensor("Lid Open Warning", icon="mdi:alert") def lid_open_warning(self) -> bool: return self._settings[0] & 8 != 0 @@ -366,8 +389,9 @@ def lid_open_warning(self, alarm: bool): self._settings[0] |= 8 else: self._settings[0] &= 247 - @property + + @sensor("Lid Open Warning Delayed", icon="mdi:alert-outline") def lid_open_warning_delayed(self) -> bool: return self._settings[0] & 16 != 0 @@ -377,8 +401,9 @@ def lid_open_warning_delayed(self, alarm: bool): self._settings[0] |= 16 else: self._settings[0] &= 239 - @property + + @sensor("Jingzhu Auto Keep Warm", icon="mdi:pot-steam") def jingzhu_auto_keep_warm(self) -> bool: return self._settings[1] & 1 != 0 @@ -388,8 +413,9 @@ def jingzhu_auto_keep_warm(self, auto_keep_warm: bool): self._settings[1] |= 1 else: self._settings[1] &= 254 - @property + + @sensor("Kuaizhu Auto Keep Warm", icon="mdi:pot-steam") def kuaizhu_auto_keep_warm(self) -> bool: return self._settings[1] & 2 != 0 @@ -399,8 +425,9 @@ def kuaizhu_auto_keep_warm(self, auto_keep_warm: bool): self._settings[1] |= 2 else: self._settings[1] &= 253 - @property + + @sensor("Zhuzhou Auto Keep Warm", icon="mdi:pot-steam") def zhuzhou_auto_keep_warm(self) -> bool: return self._settings[1] & 4 != 0 @@ -410,8 +437,9 @@ def zhuzhou_auto_keep_warm(self, auto_keep_warm: bool): self._settings[1] |= 4 else: self._settings[1] &= 251 - @property + + @sensor("Favorite Auto Keep Warm", icon="mdi:pot-steam") def favorite_auto_keep_warm(self) -> bool: return self._settings[1] & 8 != 0 @@ -468,18 +496,20 @@ def __init__(self, data): meal is ready: ['autokeepwarm', '0001', '1000000000', '031e0b23031e', '1', '750', '60', '0207', '05040f', '00030017', '0100', 'ffffffffffff011effff01000000535d'] """ self.data = data - @property + + @sensor("Mode", icon="mdi:pot-steam") def mode(self) -> OperationMode: """Current operation mode.""" return OperationMode(self.data["func"]) - @property + + @sensor("Menu", icon="mdi:book-open-variant") def menu(self) -> int: """Selected recipe id.""" return int(self.data["menu"], 16) - @property + @sensor("Stage", icon="mdi:pot-steam") def stage(self) -> CookingStage | None: """Current stage if cooking.""" stage = self.data["stage"] @@ -487,8 +517,8 @@ def stage(self) -> CookingStage | None: return CookingStage(stage) return None - @property + @sensor("Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") def temperature(self) -> int | None: """Current temperature, if idle. @@ -499,8 +529,8 @@ def temperature(self) -> int | None: return int(value) return None - @property + @sensor("Start Time", icon="mdi:clock-start") def start_time(self) -> time | None: """Start time of cooking? @@ -512,13 +542,14 @@ def start_time(self) -> time | None: return time(hour=int(value[4:6], 16), minute=int(value[6:8], 16)) return None - @property + + @sensor("Remaining", unit="min", icon="mdi:timer-outline") def remaining(self) -> int: """Remaining minutes of the cooking process.""" return int(self.data["t_func"]) - @property + @sensor("Cooking Delayed", unit="min", icon="mdi:timer-sand") def cooking_delayed(self) -> int | None: """Wait n minutes before cooking / scheduled cooking.""" delay = int(self.data["t_precook"]) @@ -527,41 +558,47 @@ def cooking_delayed(self) -> int | None: return delay return None - @property + + @sensor("Duration", unit="min", icon="mdi:timer-outline") def duration(self) -> int: """Duration of the cooking process.""" return int(self.data["t_cook"]) - @property + + @sensor("Cooker Settings", icon="mdi:cog") def cooker_settings(self) -> CookerSettings: """Settings of the cooker.""" return CookerSettings(self.data["setting"]) - @property + + @sensor("Interaction Timeouts", icon="mdi:timer-cog-outline") def interaction_timeouts(self) -> InteractionTimeouts: """Interaction timeouts.""" return InteractionTimeouts(self.data["delay"]) - @property + + @sensor("Hardware Version", icon="mdi:chip") def hardware_version(self) -> int: """Hardware version.""" return int(self.data["version"][0:4], 16) - @property + + @sensor("Firmware Version", icon="mdi:update") def firmware_version(self) -> int: """Firmware version.""" return int(self.data["version"][4:8], 16) - @property + + @sensor("Favorite", icon="mdi:star") def favorite(self) -> int: """Favored recipe id. Can be compared with the menu property. """ return int(self.data["favorite"], 16) - @property + @sensor("Custom", icon="mdi:tune") def custom(self) -> CookerCustomizations | None: custom = self.data["custom"] diff --git a/miio/integrations/deerma/humidifier/airhumidifier_jsqs.py b/miio/integrations/deerma/humidifier/airhumidifier_jsqs.py index dd9ca74fc..99f58cb06 100644 --- a/miio/integrations/deerma/humidifier/airhumidifier_jsqs.py +++ b/miio/integrations/deerma/humidifier/airhumidifier_jsqs.py @@ -5,6 +5,7 @@ import click from miio.click_common import EnumType, command, format_output +from miio.devicestatus import sensor, setting from miio.miot_device import DeviceStatus, MiotDevice _LOGGER = logging.getLogger(__name__) @@ -69,21 +70,30 @@ def __init__(self, data: dict[str, Any]) -> None: # Air Humidifier @property + @setting(name="Power", setter_name="on", icon="mdi:power") def is_on(self) -> bool: """Return True if device is on.""" return self.data["power"] @property + @sensor(name="Power", icon="mdi:power") def power(self) -> str: """Return power state.""" return "on" if self.is_on else "off" @property + @sensor(name="Error", icon="mdi:alert-circle") def error(self) -> int: """Return error state.""" return self.data["fault"] @property + @setting( + name="Mode", + setter_name="set_mode", + icon="mdi:fan", + choices=OperationMode, + ) def mode(self) -> OperationMode: """Return current operation mode.""" @@ -96,6 +106,7 @@ def mode(self) -> OperationMode: return mode @property + @setting( def target_humidity(self) -> int | None: """Return target humidity.""" return self.data.get("target_humidity") @@ -103,11 +114,13 @@ def target_humidity(self) -> int | None: # Environment @property + @sensor(name="Relative Humidity", unit="%", device_class="humidity") def relative_humidity(self) -> int | None: """Return current humidity.""" return self.data.get("relative_humidity") @property + @sensor(name="Temperature", unit="C", device_class="temperature") def temperature(self) -> float | None: """Return current temperature, if available.""" return self.data.get("temperature") @@ -115,6 +128,7 @@ def temperature(self) -> float | None: # Alarm @property + @setting(name="Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") def buzzer(self) -> bool | None: """Return True if buzzer is on.""" return self.data.get("buzzer") @@ -122,6 +136,7 @@ def buzzer(self) -> bool | None: # Indicator Light @property + @setting(name="LED Light", setter_name="set_light", icon="mdi:led-outline") def led_light(self) -> bool | None: """Return status of the LED.""" return self.data.get("led_light") @@ -129,16 +144,19 @@ def led_light(self) -> bool | None: # Other @property + @sensor(name="Tank Filed", icon="mdi:cup-water") def tank_filed(self) -> bool | None: """Return the tank filed.""" return self.data.get("tank_filed") @property + @sensor(name="Water Shortage Fault", icon="mdi:water-off") def water_shortage_fault(self) -> bool | None: """Return water shortage fault.""" return self.data.get("water_shortage_fault") @property + @setting(name="Overwet Protect", setter_name="set_overwet_protect", icon="mdi:shield-check") def overwet_protect(self) -> bool | None: """Return True if overwet mode is active.""" return self.data.get("overwet_protect") diff --git a/miio/integrations/deerma/humidifier/airhumidifier_mjjsq.py b/miio/integrations/deerma/humidifier/airhumidifier_mjjsq.py index 5fc93705b..fe7655a33 100644 --- a/miio/integrations/deerma/humidifier/airhumidifier_mjjsq.py +++ b/miio/integrations/deerma/humidifier/airhumidifier_mjjsq.py @@ -7,6 +7,7 @@ from miio import Device, DeviceStatus from miio.click_common import EnumType, command, format_output +from miio.devicestatus import sensor, setting _LOGGER = logging.getLogger(__name__) @@ -55,16 +56,24 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property + @sensor(name="Power", icon="mdi:power") def power(self) -> str: """Power state.""" return "on" if self.data["OnOff_State"] == 1 else "off" @property + @setting(name="Power", setter_name="on", icon="mdi:power") def is_on(self) -> bool: """True if device is turned on.""" return self.power == "on" @property + @setting( + name="Mode", + setter_name="set_mode", + icon="mdi:fan", + choices=OperationMode, + ) def mode(self) -> OperationMode: """Operation mode. @@ -73,41 +82,56 @@ def mode(self) -> OperationMode: return OperationMode(self.data["Humidifier_Gear"]) @property + @sensor(name="Temperature", unit="C", device_class="temperature") def temperature(self) -> int: """Current temperature in degree celsius.""" return self.data["TemperatureValue"] @property + @sensor(name="Humidity", unit="%", device_class="humidity") def humidity(self) -> int: """Current humidity in percent.""" return self.data["Humidity_Value"] @property + @setting(name="Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") def buzzer(self) -> bool: """True if buzzer is turned on.""" return self.data["TipSound_State"] == 1 @property + @setting(name="LED", setter_name="set_led", icon="mdi:led-outline") def led(self) -> bool: """True if LED is turned on.""" return self.data["Led_State"] == 1 @property + @setting( + name="Target Humidity", + setter_name="set_target_humidity", + unit="%", + icon="mdi:water-percent", + min_value=0, + max_value=99, + ) def target_humidity(self) -> int: """Target humiditiy in percent.""" return self.data["HumiSet_Value"] @property + @sensor(name="No Water", icon="mdi:water-off") def no_water(self) -> bool: """True if the water tank is empty.""" return self.data["waterstatus"] == 0 @property + @sensor(name="Water Tank Detached", icon="mdi:cup-water") def water_tank_detached(self) -> bool: """True if the water tank is detached.""" return self.data["watertankstatus"] == 0 @property + @setting(name="Wet Protection", setter_name="set_wet_protection", icon="mdi:shield-check") def wet_protection(self) -> bool | None: """True if wet protection is enabled.""" if self.data["wet_and_protect"] is not None: @@ -116,6 +140,7 @@ def wet_protection(self) -> bool | None: return None @property + @sensor(name="Use Time", unit="s", icon="mdi:timer") def use_time(self) -> int | None: """How long the device has been active in seconds. diff --git a/miio/integrations/dmaker/airfresh/airfresh_t2017.py b/miio/integrations/dmaker/airfresh/airfresh_t2017.py index 9abf695d4..4d66826eb 100644 --- a/miio/integrations/dmaker/airfresh/airfresh_t2017.py +++ b/miio/integrations/dmaker/airfresh/airfresh_t2017.py @@ -7,6 +7,7 @@ from miio import Device, DeviceStatus from miio.click_common import EnumType, command, format_output +from miio.devicestatus import sensor, setting _LOGGER = logging.getLogger(__name__) @@ -115,71 +116,96 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property + @sensor("Power", icon="mdi:power") def power(self) -> str: """Power state.""" return "on" if self.data["power"] else "off" @property + @sensor("Is On", icon="mdi:power") def is_on(self) -> bool: """Return True if device is on.""" return self.data["power"] @property + @setting("Mode", setter_name="set_mode", choices=OperationMode, icon="mdi:fan") def mode(self) -> OperationMode: """Current operation mode.""" return OperationMode(self.data["mode"]) @property + @sensor("PM2.5", unit="μg/m³", device_class="pm25", icon="mdi:blur") def pm25(self) -> int: """Fine particulate patter (PM2.5).""" return self.data["pm25"] @property + @sensor( + "CO2", + unit="ppm", + device_class="carbon_dioxide", + icon="mdi:molecule-co2", + ) def co2(self) -> int: """Carbon dioxide.""" return self.data["co2"] @property + @sensor("Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") def temperature(self) -> int: """Current temperature in degree celsions.""" return self.data["temperature_outside"] @property + @setting( + "Favorite Speed", + setter_name="set_favorite_speed", + min_value=0, + max_value=150, + icon="mdi:fan", + ) def favorite_speed(self) -> int: """Favorite speed.""" return self.data["favourite_speed"] @property + @sensor("Control Speed", icon="mdi:fan") def control_speed(self) -> int: """Control speed.""" return self.data["control_speed"] @property + @sensor("Dust Filter Life Remaining", unit="%", icon="mdi:filter") def dust_filter_life_remaining(self) -> int | None: """Remaining dust filter life in percent.""" return self.data.get("filter_intermediate", self.data.get("filter_rate")) @property + @sensor("Dust Filter Life Remaining Days", unit="days", icon="mdi:filter") def dust_filter_life_remaining_days(self) -> int | None: """Remaining dust filter life in days.""" return self.data.get("filter_inter_day", self.data.get("filter_day")) @property + @sensor("Upper Filter Life Remaining", unit="%", icon="mdi:filter") def upper_filter_life_remaining(self) -> int | None: """Remaining upper filter life in percent.""" return self.data.get("filter_efficient") @property + @sensor("Upper Filter Life Remaining Days", unit="days", icon="mdi:filter") def upper_filter_life_remaining_days(self) -> int | None: """Remaining upper filter life in days.""" return self.data.get("filter_effi_day") @property + @setting("PTC", setter_name="set_ptc", icon="mdi:radiator") def ptc(self) -> bool: """Return True if PTC is on.""" return self.data["ptc_on"] @property + @setting("PTC Level", setter_name="set_ptc_level", choices=PtcLevel, icon="mdi:radiator") def ptc_level(self) -> PtcLevel | None: """PTC level.""" try: @@ -188,26 +214,31 @@ def ptc_level(self) -> PtcLevel | None: return None @property + @sensor("PTC Status", icon="mdi:radiator") def ptc_status(self) -> bool: """Return true if PTC status is on.""" return self.data["ptc_status"] @property + @setting("Child Lock", setter_name="set_child_lock", icon="mdi:lock") def child_lock(self) -> bool: """Return True if child lock is on.""" return self.data["child_lock"] @property + @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") def buzzer(self) -> bool: """Return True if sound is on.""" return self.data["sound"] @property + @setting("Display", setter_name="set_display", icon="mdi:monitor") def display(self) -> bool: """Return True if the display is on.""" return self.data["display"] @property + @setting( def display_orientation(self) -> DisplayOrientation | None: """Display orientation.""" try: diff --git a/miio/integrations/dmaker/fan/fan.py b/miio/integrations/dmaker/fan/fan.py index e2a4220b4..ca803d143 100644 --- a/miio/integrations/dmaker/fan/fan.py +++ b/miio/integrations/dmaker/fan/fan.py @@ -5,6 +5,7 @@ from miio import Device, DeviceStatus from miio.click_common import EnumType, command, format_output +from miio.devicestatus import sensor, setting class MoveDirection(enum.Enum): @@ -49,51 +50,80 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property + @sensor("Power", icon="mdi:power") def power(self) -> str: """Power state.""" return "on" if self.data["power"] else "off" @property + @sensor("Is On", icon="mdi:power") def is_on(self) -> bool: """True if device is currently on.""" return self.data["power"] @property + @setting( + "Mode", + setter_name="set_mode", + choices=OperationMode, + icon="mdi:fan", + ) def mode(self) -> OperationMode: """Operation mode.""" return OperationMode(self.data["mode"]) @property + @setting( + "Speed", + unit="%", + setter_name="set_speed", + min_value=0, + max_value=100, + icon="mdi:speedometer", + ) def speed(self) -> int: """Speed of the motor.""" return self.data["speed"] @property + @setting("Oscillate", setter_name="set_oscillate", icon="mdi:sync") def oscillate(self) -> bool: """True if oscillation is enabled.""" return self.data["roll_enable"] @property + @setting( + "Angle", + unit="°", + setter_name="set_angle", + min_value=30, + max_value=140, + icon="mdi:angle-acute", + ) def angle(self) -> int: """Oscillation angle.""" return self.data["roll_angle"] @property + @sensor("Delay Off Countdown", unit="s", icon="mdi:timer-sand", device_class="duration") def delay_off_countdown(self) -> int: """Countdown until turning off in seconds.""" return self.data["time_off"] @property + @setting("LED", setter_name="set_led", icon="mdi:led-on") def led(self) -> bool: """True if LED is turned on, if available.""" return self.data["light"] @property + @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") def buzzer(self) -> bool: """True if buzzer is turned on.""" return self.data["beep_sound"] @property + @setting("Child Lock", setter_name="set_child_lock", icon="mdi:lock") def child_lock(self) -> bool: """True if child lock is on.""" return self.data["child_lock"] diff --git a/miio/integrations/dmaker/fan/fan_miot.py b/miio/integrations/dmaker/fan/fan_miot.py index 28b73564b..90adbcf59 100644 --- a/miio/integrations/dmaker/fan/fan_miot.py +++ b/miio/integrations/dmaker/fan/fan_miot.py @@ -5,6 +5,7 @@ from miio import DeviceStatus, MiotDevice from miio.click_common import EnumType, command, format_output +from miio.devicestatus import sensor, setting class OperationMode(enum.Enum): @@ -189,16 +190,19 @@ def __init__(self, data: dict[str, Any], model: str) -> None: self.model = model @property + @sensor("Power", icon="mdi:power") def power(self) -> str: """Power state.""" return "on" if self.data["power"] else "off" @property + @sensor("Is On", icon="mdi:power") def is_on(self) -> bool: """True if device is currently on.""" return self.data["power"] @property + @setting("Mode", setter_name="set_mode", choices=OperationMode, icon="mdi:fan") def mode(self) -> OperationMode: """Operation mode.""" if self.model == MODEL_FAN_P45: @@ -206,36 +210,50 @@ def mode(self) -> OperationMode: return OperationMode[OperationModeMiot(self.data["mode"]).name] @property + @setting("Speed", setter_name="set_speed", min_value=0, max_value=100, icon="mdi:fan") def speed(self) -> int: """Speed of the motor.""" return self.data["fan_speed"] @property + @setting("Oscillate", setter_name="set_oscillate", icon="mdi:arrow-oscillating") def oscillate(self) -> bool: """True if oscillation is enabled.""" return self.data["swing_mode"] @property + @setting("Angle", setter_name="set_angle", icon="mdi:angle-acute") def angle(self) -> int: """Oscillation angle.""" return self.data["swing_mode_angle"] @property + @setting( + "Delay Off Countdown", + setter_name="delay_off", + unit="min", + min_value=0, + max_value=480, + icon="mdi:timer", + ) def delay_off_countdown(self) -> int: """Countdown until turning off in minutes.""" return self.data["power_off_time"] @property + @setting("LED", setter_name="set_led", icon="mdi:led-on") def led(self) -> bool: """True if LED is turned on, if available.""" return self.data["light"] @property + @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") def buzzer(self) -> bool: """True if buzzer is turned on.""" return self.data["buzzer"] @property + @setting("Child Lock", setter_name="set_child_lock", icon="mdi:lock") def child_lock(self) -> bool: """True if child lock is on.""" return self.data["child_lock"] @@ -265,46 +283,62 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property + @sensor("Power", icon="mdi:power") def power(self) -> str: """Power state.""" return "on" if self.data["power"] else "off" @property + @sensor("Is On", icon="mdi:power") def is_on(self) -> bool: """True if device is currently on.""" return self.data["power"] @property + @setting("Mode", setter_name="set_mode", choices=OperationMode, icon="mdi:fan") def mode(self) -> OperationMode: """Operation mode.""" return OperationMode[OperationModeMiot(self.data["mode"]).name] @property + @setting("Speed", setter_name="set_speed", min_value=1, max_value=3, icon="mdi:fan") def speed(self) -> int: """Speed of the motor.""" return self.data["fan_level"] @property + @setting("Oscillate", setter_name="set_oscillate", icon="mdi:arrow-oscillating") def oscillate(self) -> bool: """True if oscillation is enabled.""" return self.data["swing_mode"] @property + @setting( + "Delay Off Countdown", + setter_name="delay_off", + unit="min", + min_value=0, + max_value=480, + icon="mdi:timer", + ) def delay_off_countdown(self) -> int: """Countdown until turning off in minutes.""" return self.data["power_off_time"] @property + @setting("LED", setter_name="set_led", icon="mdi:led-on") def led(self) -> bool: """True if LED is turned on.""" return self.data["light"] @property + @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") def buzzer(self) -> bool: """True if buzzer is turned on.""" return self.data["buzzer"] @property + @setting("Child Lock", setter_name="set_child_lock", icon="mdi:lock") def child_lock(self) -> bool: """True if child lock is on.""" return self.data["child_lock"] diff --git a/miio/integrations/dreame/vacuum/dreamevacuum_miot.py b/miio/integrations/dreame/vacuum/dreamevacuum_miot.py index 0bcd4c01a..6b7d13ca3 100644 --- a/miio/integrations/dreame/vacuum/dreamevacuum_miot.py +++ b/miio/integrations/dreame/vacuum/dreamevacuum_miot.py @@ -7,6 +7,7 @@ import click from miio.click_common import command, format_output +from miio.devicestatus import sensor, setting from miio.miot_device import DeviceStatus as DeviceStatusContainer from miio.miot_device import MiotDevice, MiotMapping from miio.updater import OneShotServer @@ -303,120 +304,141 @@ class DreameVacuumStatus(DeviceStatusContainer): def __init__(self, data, model): self.data = data self.model = model - @property + + @sensor("Battery Level", unit="%", device_class="battery", icon="mdi:battery") def battery_level(self) -> str: return self.data["battery_level"] - @property + + @sensor("Brush Left Time", unit="h", icon="mdi:brush") def brush_left_time(self) -> str: return self.data["brush_left_time"] - @property + + @sensor("Side Brush Left Time", unit="h", icon="mdi:brush") def brush_left_time2(self) -> str: return self.data["brush_left_time2"] - @property + + @sensor("Side Brush Life Level", unit="%", icon="mdi:brush") def brush_life_level2(self) -> str: return self.data["brush_life_level2"] - @property + + @sensor("Brush Life Level", unit="%", icon="mdi:brush") def brush_life_level(self) -> str: return self.data["brush_life_level"] - @property + + @sensor("Filter Left Time", unit="h", icon="mdi:filter-outline") def filter_left_time(self) -> str: return self.data["filter_left_time"] - @property + + @sensor("Filter Life Level", unit="%", icon="mdi:filter-outline") def filter_life_level(self) -> str: return self.data["filter_life_level"] - @property + @sensor("Device Fault", icon="mdi:alert-circle") def device_fault(self) -> FaultStatus | None: try: return FaultStatus(self.data["device_fault"]) except ValueError: _LOGGER.error("Unknown FaultStatus (%s)", self.data["device_fault"]) return None - @property + @sensor("Charging State", icon="mdi:battery-charging") def charging_state(self) -> ChargingState | None: try: return ChargingState(self.data["charging_state"]) except ValueError: _LOGGER.error("Unknown ChargingStats (%s)", self.data["charging_state"]) return None - @property + @sensor("Operating Mode", icon="mdi:robot-vacuum") def operating_mode(self) -> OperatingMode | None: try: return OperatingMode(self.data["operating_mode"]) except ValueError: _LOGGER.error("Unknown OperatingMode (%s)", self.data["operating_mode"]) return None - @property + @sensor("Device Status", icon="mdi:robot-vacuum") def device_status(self) -> DeviceStatus | None: try: return DeviceStatus(self.data["device_status"]) except TypeError: _LOGGER.error("Unknown DeviceStatus (%s)", self.data["device_status"]) return None - @property + + @sensor("Timer Enable", icon="mdi:timer") def timer_enable(self) -> str: return self.data["timer_enable"] - @property + + @sensor("Start Time", icon="mdi:clock-start") def start_time(self) -> str: return self.data["start_time"] - @property + + @sensor("Stop Time", icon="mdi:clock-end") def stop_time(self) -> str: return self.data["stop_time"] - @property + + @sensor("Map View", icon="mdi:map") def map_view(self) -> str: return self.data["map_view"] - @property + + @setting("Volume", setter_name="set_sound_volume", unit="%", min_value=0, max_value=100, step=1, icon="mdi:volume-high") def volume(self) -> str: return self.data["volume"] - @property + + @sensor("Voice Package", icon="mdi:account-voice") def voice_package(self) -> str: return self.data["voice_package"] - @property + + @sensor("Timezone", icon="mdi:earth") def timezone(self) -> str: return self.data["timezone"] - @property + + @sensor("Cleaning Time", unit="min", icon="mdi:timer-outline") def cleaning_time(self) -> str: return self.data["cleaning_time"] - @property + + @sensor("Cleaning Area", unit="m²", icon="mdi:texture-box") def cleaning_area(self) -> str: return self.data["cleaning_area"] - @property + + @sensor("First Clean Time", icon="mdi:clock-outline") def first_clean_time(self) -> str: return self.data["first_clean_time"] - @property + + @sensor("Total Clean Time", unit="min", icon="mdi:timer-outline") def total_clean_time(self) -> str: return self.data["total_clean_time"] - @property + + @sensor("Total Clean Times", icon="mdi:counter") def total_clean_times(self) -> str: return self.data["total_clean_times"] - @property + + @sensor("Total Clean Area", unit="m²", icon="mdi:texture-box") def total_clean_area(self) -> str: return self.data["total_clean_area"] - @property + + @setting("Cleaning Mode", setter_name="set_fan_speed", icon="mdi:fan") def cleaning_mode(self): cleaning_mode = self.data["cleaning_mode"] cleaning_mode_enum_class = _get_cleaning_mode_enum_class(self.model) @@ -429,21 +451,22 @@ def cleaning_mode(self): except ValueError: _LOGGER.error(f"Unknown CleaningMode ({cleaning_mode})") return None - @property + @sensor("Life Sieve", unit="%", icon="mdi:filter-outline") def life_sieve(self) -> str | None: return self.data.get("life_sieve") - @property + @sensor("Life Brush Side", unit="%", icon="mdi:brush") def life_brush_side(self) -> str | None: return self.data.get("life_brush_side") - @property + @sensor("Life Brush Main", unit="%", icon="mdi:brush") def life_brush_main(self) -> str | None: return self.data.get("life_brush_main") # TODO: get/set water flow for Dreame 1C @property + @setting("Water Flow", setter_name="set_waterflow", choices=WaterFlow, icon="mdi:water") def water_flow(self) -> WaterFlow | None: try: water_flow = self.data["water_flow"] @@ -454,8 +477,8 @@ def water_flow(self) -> WaterFlow | None: except ValueError: _LOGGER.error("Unknown WaterFlow (%s)", self.data["water_flow"]) return None - @property + @sensor("Water Box Carriage Attached", icon="mdi:cup-water") def is_water_box_carriage_attached(self) -> bool | None: """Return True if water box carriage (mop) is installed, None if sensor not present.""" diff --git a/miio/integrations/huayi/light/huizuo.py b/miio/integrations/huayi/light/huizuo.py index a5bd0076a..98a446ae5 100644 --- a/miio/integrations/huayi/light/huizuo.py +++ b/miio/integrations/huayi/light/huizuo.py @@ -11,6 +11,7 @@ from miio import DeviceStatus, MiotDevice, UnsupportedFeatureException from miio.click_common import command, format_output +from miio.devicestatus import sensor, setting _LOGGER = logging.getLogger(__name__) @@ -117,21 +118,40 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property + @sensor("Is On", icon="mdi:power") def is_on(self) -> bool: """Return True if device is on.""" return self.data["power"] @property + @setting( + "Brightness", + unit="%", + setter_name="set_brightness", + min_value=0, + max_value=100, + icon="mdi:brightness-6", + ) def brightness(self) -> int: """Return current brightness.""" return self.data["brightness"] @property + @setting( + "Color Temperature", + unit="K", + setter_name="set_color_temp", + min_value=3000, + max_value=6400, + icon="mdi:thermometer", + device_class="temperature", + ) def color_temp(self) -> int: """Return current color temperature.""" return self.data["color_temp"] @property + @sensor("Fan On", icon="mdi:fan") def is_fan_on(self) -> bool | None: """Return True if Fan is on.""" if "fan_power" in self.data: @@ -139,6 +159,7 @@ def is_fan_on(self) -> bool | None: return None @property + @setting( def fan_speed_level(self) -> int | None: """Return current Fan speed level.""" if "fan_level" in self.data: @@ -146,6 +167,7 @@ def fan_speed_level(self) -> int | None: return None @property + @sensor("Fan Reverse", icon="mdi:fan-chevron-down") def is_fan_reverse(self) -> bool | None: """Return True if Fan reverse is on.""" if "fan_motor_reverse" in self.data: @@ -153,6 +175,7 @@ def is_fan_reverse(self) -> bool | None: return None @property + @sensor("Fan Mode", icon="mdi:fan-auto") def fan_mode(self) -> int | None: """Return 0 if 'Basic' and 1 if 'Natural wind'.""" if "fan_mode" in self.data: @@ -160,6 +183,7 @@ def fan_mode(self) -> int | None: return None @property + @sensor("Heater On", icon="mdi:radiator") def is_heater_on(self) -> bool | None: """Return True if Heater is on.""" if "heater_power" in self.data: @@ -167,6 +191,7 @@ def is_heater_on(self) -> bool | None: return None @property + @sensor("Heater Fault Code", icon="mdi:alert-circle") def heater_fault_code(self) -> int | None: """Return Heater's fault code. @@ -177,6 +202,7 @@ def heater_fault_code(self) -> int | None: return None @property + @setting( def heat_level(self) -> int | None: """Return Heater's heat level.""" if "heat_level" in self.data: diff --git a/miio/integrations/ksmb/walkingpad/walkingpad.py b/miio/integrations/ksmb/walkingpad/walkingpad.py index 7384a015d..3fec93a4d 100644 --- a/miio/integrations/ksmb/walkingpad/walkingpad.py +++ b/miio/integrations/ksmb/walkingpad/walkingpad.py @@ -7,6 +7,7 @@ from miio import Device, DeviceException, DeviceStatus from miio.click_common import EnumType, command, format_output +from miio.devicestatus import sensor, setting _LOGGER = logging.getLogger(__name__) @@ -43,51 +44,85 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property + @sensor("Power", icon="mdi:power") def power(self) -> str: """Power state.""" return self.data["power"] @property + @sensor("Is On", icon="mdi:power") def is_on(self) -> bool: """True if the device is turned on.""" return self.power == "on" @property + @sensor("Walking Time", icon="mdi:timer", device_class="duration") def walking_time(self) -> timedelta: """Current walking duration in seconds.""" return timedelta(seconds=int(self.data["time"])) @property + @setting( + "Speed", + unit="km/h", + setter_name="set_speed", + min_value=0, + max_value=6, + icon="mdi:speedometer", + ) def speed(self) -> float: """Current speed.""" return float(self.data["sp"]) @property + @setting( + "Start Speed", + unit="km/h", + setter_name="set_start_speed", + min_value=0, + max_value=6, + icon="mdi:speedometer-slow", + ) def start_speed(self) -> float: """Current start speed.""" return self.data["start_speed"] @property + @setting( + "Mode", + setter_name="set_mode", + choices=OperationMode, + icon="mdi:run", + ) def mode(self) -> OperationMode: """Current mode.""" return OperationMode(self.data["mode"]) @property + @setting( + "Sensitivity", + setter_name="set_sensitivity", + choices=OperationSensitivity, + icon="mdi:tune", + ) def sensitivity(self) -> OperationSensitivity: """Current sensitivity.""" return OperationSensitivity(self.data["sensitivity"]) @property + @sensor("Step Count", icon="mdi:shoe-print") def step_count(self) -> int: """Current steps.""" return int(self.data["step"]) @property + @sensor("Distance", unit="m", icon="mdi:map-marker-distance") def distance(self) -> int: """Current distance in meters.""" return int(self.data["dist"]) @property + @sensor("Calories", unit="cal", icon="mdi:fire") def calories(self) -> int: """Current calories burnt.""" return int(self.data["cal"]) diff --git a/miio/integrations/leshow/fan/fan_leshow.py b/miio/integrations/leshow/fan/fan_leshow.py index 6f553227a..6109959d6 100644 --- a/miio/integrations/leshow/fan/fan_leshow.py +++ b/miio/integrations/leshow/fan/fan_leshow.py @@ -6,6 +6,7 @@ from miio import Device, DeviceStatus from miio.click_common import EnumType, command, format_output +from miio.devicestatus import sensor, setting _LOGGER = logging.getLogger(__name__) @@ -45,41 +46,71 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property + @sensor("Power", icon="mdi:power") def power(self) -> str: """Power state.""" return "on" if self.data["power"] == 1 else "off" @property + @sensor("Is On", icon="mdi:power") def is_on(self) -> bool: """True if device is turned on.""" return self.data["power"] == 1 @property + @setting( + "Mode", + setter_name="set_mode", + icon="mdi:fan", + choices=OperationMode, + ) def mode(self) -> OperationMode: """Operation mode.""" return OperationMode(self.data["mode"]) @property + @setting( + "Speed", + setter_name="set_speed", + icon="mdi:speedometer", + unit="%", + min_value=0, + max_value=100, + step=1, + ) def speed(self) -> int: """Speed of the fan in percent.""" return self.data["blow"] @property + @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") def buzzer(self) -> bool: """True if buzzer is turned on.""" return self.data["sound"] == 1 @property + @setting("Oscillate", setter_name="set_oscillate", icon="mdi:rotate-3d-variant") def oscillate(self) -> bool: """True if oscillation is enabled.""" return self.data["yaw"] == 1 @property + @setting( + "Delay Off Countdown", + setter_name="delay_off", + icon="mdi:timer", + device_class="duration", + unit="min", + min_value=0, + max_value=540, + step=1, + ) def delay_off_countdown(self) -> int: """Countdown until turning off in minutes.""" return self.data["timer"] @property + @sensor("Error Detected", icon="mdi:alert-circle") def error_detected(self) -> bool: """True if a fault was detected.""" return self.data["fault"] == 1 diff --git a/miio/integrations/lumi/acpartner/airconditioningcompanion.py b/miio/integrations/lumi/acpartner/airconditioningcompanion.py index 24da4d035..ac4eed78f 100644 --- a/miio/integrations/lumi/acpartner/airconditioningcompanion.py +++ b/miio/integrations/lumi/acpartner/airconditioningcompanion.py @@ -5,6 +5,7 @@ from miio import Device, DeviceStatus from miio.click_common import EnumType, command, format_output +from miio.devicestatus import sensor _LOGGER = logging.getLogger(__name__) @@ -97,11 +98,13 @@ def __init__(self, data): self.state = data["model_and_state"][1] @property + @sensor("Load Power", unit="W", device_class="power", icon="mdi:flash") def load_power(self) -> int: """Current power load of the air conditioner.""" return int(self.data["model_and_state"][2]) @property + @sensor("Power Socket", icon="mdi:power-socket") def power_socket(self) -> str | None: """Current socket power state.""" if "power_socket" in self.data and self.data["power_socket"] is not None: @@ -110,21 +113,25 @@ def power_socket(self) -> str | None: return None @property + @sensor("Air Condition Model", icon="mdi:air-conditioner") def air_condition_model(self) -> bytes: """Model of the air conditioner.""" return bytes.fromhex(self.model) @property + @sensor("Model Format", icon="mdi:information-outline") def model_format(self) -> int: """Version number of the model format.""" return self.air_condition_model[0] @property + @sensor("Device Type", icon="mdi:devices") def device_type(self) -> int: """Device type identifier.""" return self.air_condition_model[1] @property + @sensor("Air Condition Brand", icon="mdi:tag") def air_condition_brand(self) -> int: """Brand of the air conditioner. @@ -133,6 +140,7 @@ def air_condition_brand(self) -> int: return int(self.air_condition_model[2:4].hex(), 16) @property + @sensor("Air Condition Remote", icon="mdi:remote") def air_condition_remote(self) -> int: """Remote id. @@ -148,6 +156,7 @@ def air_condition_remote(self) -> int: return int(self.air_condition_model[4:8].hex(), 16) @property + @sensor("State Format", icon="mdi:information-outline") def state_format(self) -> int: """Version number of the state format. @@ -156,15 +165,18 @@ def state_format(self) -> int: return int(self.air_condition_model[8]) @property + @sensor("Air Condition Configuration", icon="mdi:cog") def air_condition_configuration(self) -> int: return self.state[2:10] @property + @sensor("Power", icon="mdi:power") def power(self) -> str: """Current power state.""" return "on" if int(self.state[2:3]) == Power.On.value else "off" @property + @sensor("LED", icon="mdi:led-on") def led(self) -> bool | None: """Current LED state.""" state = self.state[8:9] @@ -178,11 +190,13 @@ def led(self) -> bool | None: return None @property + @sensor("Is On", icon="mdi:power") def is_on(self) -> bool: """True if the device is turned on.""" return self.power == "on" @property + @sensor("Target Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") def target_temperature(self) -> int | None: """Target temperature.""" try: @@ -191,6 +205,7 @@ def target_temperature(self) -> int | None: return None @property + @sensor("Swing Mode", icon="mdi:arrow-oscillating") def swing_mode(self) -> SwingMode | None: """Current swing mode.""" try: @@ -200,6 +215,7 @@ def swing_mode(self) -> SwingMode | None: return None @property + @sensor("Fan Speed", icon="mdi:fan") def fan_speed(self) -> FanSpeed | None: """Current fan speed.""" try: @@ -209,6 +225,7 @@ def fan_speed(self) -> FanSpeed | None: return None @property + @sensor("Mode", icon="mdi:air-conditioner") def mode(self) -> OperationMode | None: """Current operation mode.""" try: diff --git a/miio/integrations/lumi/acpartner/airconditioningcompanionMCN.py b/miio/integrations/lumi/acpartner/airconditioningcompanionMCN.py index ba6b57db6..59edff359 100644 --- a/miio/integrations/lumi/acpartner/airconditioningcompanionMCN.py +++ b/miio/integrations/lumi/acpartner/airconditioningcompanionMCN.py @@ -5,6 +5,7 @@ from miio import Device, DeviceStatus from miio.click_common import command, format_output +from miio.devicestatus import sensor, setting _LOGGER = logging.getLogger(__name__) @@ -44,21 +45,25 @@ def __init__(self, data): self.data = data @property + @sensor("Load Power", unit="W", icon="mdi:flash", device_class="power") def load_power(self) -> int: """Current power load of the air conditioner.""" return int(self.data[-1]) @property + @sensor("Power", icon="mdi:power") def power(self) -> str: """Current power state.""" return self.data[0] @property + @setting("Power", setter_name="on", icon="mdi:power") def is_on(self) -> bool: """True if the device is turned on.""" return self.power == "on" @property + @setting("Mode", setter_name="send_command", icon="mdi:air-conditioner", choices=OperationMode) def mode(self) -> OperationMode | None: """Current operation mode.""" try: @@ -68,6 +73,7 @@ def mode(self) -> OperationMode | None: return None @property + @setting("Target Temperature", setter_name="send_command", unit="°C", icon="mdi:thermometer", device_class="temperature") def target_temperature(self) -> int | None: """Target temperature.""" try: @@ -76,6 +82,7 @@ def target_temperature(self) -> int | None: return None @property + @setting("Fan Speed", setter_name="send_command", icon="mdi:fan", choices=FanSpeed) def fan_speed(self) -> FanSpeed | None: """Current fan speed.""" try: @@ -85,6 +92,7 @@ def fan_speed(self) -> FanSpeed | None: return None @property + @setting("Swing Mode", setter_name="send_command", icon="mdi:arrow-oscillating", choices=SwingMode) def swing_mode(self) -> SwingMode | None: """Current swing mode.""" try: diff --git a/miio/integrations/lumi/camera/aqaracamera.py b/miio/integrations/lumi/camera/aqaracamera.py index 2a5a0cc4b..e9d4ccdc8 100644 --- a/miio/integrations/lumi/camera/aqaracamera.py +++ b/miio/integrations/lumi/camera/aqaracamera.py @@ -17,6 +17,7 @@ from miio import Device, DeviceStatus from miio.click_common import command, format_output +from miio.devicestatus import sensor, setting _LOGGER = logging.getLogger(__name__) @@ -75,46 +76,59 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property + @sensor("Type", icon="mdi:camera") def type(self) -> str: """TODO: Type of the camera? Name?""" return self.data["app_type"] @property + @sensor("Video Status", icon="mdi:video") def video_status(self) -> bool: """Video state.""" return bool(self.data["video_state"]) @property + @sensor("Is On", icon="mdi:video") def is_on(self) -> bool: """True if device is currently on.""" return self.video_status == 1 @property + @setting("Motion Detection", setter_name="md_on", icon="mdi:motion-sensor") def md(self) -> bool: """Motion detection state.""" return bool(self.data["md_status"]) @property + @setting( + "Motion Detection Sensitivity", + setter_name="md_sensitivity", + icon="mdi:motion-sensor", + ) def md_sensitivity(self): """Motion detection sensitivity.""" return self.data["mdsensitivity"] @property + @setting("IR Mode", setter_name="ir_on", icon="mdi:remote") def ir(self): """IR mode.""" return bool(self.data["ir_status"]) @property + @setting("LED", setter_name="led_on", icon="mdi:led-on") def led(self): """LED status.""" return bool(self.data["led_status"]) @property + @setting("Flipped", setter_name="flip_on", icon="mdi:flip-vertical") def flipped(self) -> bool: """TODO: If camera is flipped?""" return self.data["flip_state"] @property + @sensor("Camera Offsets", icon="mdi:camera-control") def offsets(self) -> CameraOffset: """Camera offset information.""" return CameraOffset( @@ -124,26 +138,31 @@ def offsets(self) -> CameraOffset: ) @property + @sensor("Channel ID", icon="mdi:access-point-network") def channel_id(self) -> int: """TODO: Zigbee channel?""" return self.data["channel_id"] @property + @setting("Fullstop", setter_name="fullstop_on", icon="mdi:alarm-light") def fullstop(self) -> bool: """Is alarm triggered by MD.""" return self.data["fullstop"] != 0 @property + @sensor("P2P ID", icon="mdi:identifier") def p2p_id(self) -> str: """P2P ID for video and audio.""" return self.data["p2p_id"] @property + @sensor("AV ID", icon="mdi:identifier") def av_id(self) -> str: """TODO: What is this? ID for the cloud?""" return self.data["avID"] @property + @sensor("AV Password", icon="mdi:lock") def av_password(self) -> str: """TODO: What is this? Password for the cloud?""" return self.data["avPass"] diff --git a/miio/integrations/lumi/curtain/curtain_youpin.py b/miio/integrations/lumi/curtain/curtain_youpin.py index a64fa3fa5..d34020338 100644 --- a/miio/integrations/lumi/curtain/curtain_youpin.py +++ b/miio/integrations/lumi/curtain/curtain_youpin.py @@ -6,6 +6,7 @@ from miio import DeviceStatus, MiotDevice from miio.click_common import EnumType, command, format_output +from miio.devicestatus import sensor, setting _LOGGER = logging.getLogger(__name__) @@ -73,46 +74,75 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property + @sensor("Status", icon="mdi:curtains") def status(self) -> Status: """Device status.""" return Status(self.data["status"]) @property + @setting("Manual Enabled", setter_name="set_manual_enabled", icon="mdi:hand-back-left") def is_manual_enabled(self) -> bool: """True if manual controls are enabled.""" return bool(self.data["is_manual_enabled"]) @property + @setting( + "Polarity", + setter_name="set_polarity", + icon="mdi:swap-horizontal", + choices=Polarity, + ) def polarity(self) -> Polarity: """Motor rotation polarity.""" return Polarity(self.data["polarity"]) @property + @setting("Position Limited", setter_name="set_position_limit", icon="mdi:arrow-collapse-horizontal") def is_position_limited(self) -> bool: """Position limit.""" return bool(self.data["is_position_limited"]) @property + @setting("Night Tip Light", setter_name="set_night_tip_light", icon="mdi:lightbulb-night") def night_tip_light(self) -> bool: """Night tip light status.""" return bool(self.data["night_tip_light"]) @property + @sensor("Run Time", icon="mdi:timer-outline", device_class="duration", unit="s") def run_time(self) -> int: """Run time of the motor.""" return self.data["run_time"] @property + @sensor("Current Position", icon="mdi:curtains", unit="%") def current_position(self) -> int: """Current curtain position.""" return self.data["current_position"] @property + @setting( + "Target Position", + setter_name="set_target_position", + icon="mdi:curtains", + unit="%", + min_value=0, + max_value=100, + step=1, + ) def target_position(self) -> int: """Target curtain position.""" return self.data["target_position"] @property + @setting( + "Adjust Value", + setter_name="set_adjust_value", + icon="mdi:tune", + min_value=-100, + max_value=100, + step=1, + ) def adjust_value(self) -> int: """Adjust value.""" return self.data["adjust_value"] diff --git a/miio/integrations/mijia/vacuum/g1vacuum.py b/miio/integrations/mijia/vacuum/g1vacuum.py index b8fbe8dc6..bfd6904a1 100644 --- a/miio/integrations/mijia/vacuum/g1vacuum.py +++ b/miio/integrations/mijia/vacuum/g1vacuum.py @@ -5,6 +5,7 @@ import click from miio.click_common import EnumType, command, format_output +from miio.devicestatus import sensor, setting from miio.miot_device import DeviceStatus, MiotDevice _LOGGER = logging.getLogger(__name__) @@ -157,23 +158,27 @@ def __init__(self, data): ] """ self.data = data - @property + + @sensor("Battery", unit="%", device_class="battery", icon="mdi:battery") def battery(self) -> int: """Battery Level.""" return self.data["battery"] - @property + + @sensor("Charge State", icon="mdi:battery-charging") def charge_state(self) -> G1ChargeState: """Charging State.""" return G1ChargeState(self.data["charge_state"]) - @property + + @sensor("Error Code", icon="mdi:alert-circle") def error_code(self) -> int: """Error code as returned by the device.""" return int(self.data["error_code"]) - @property + + @sensor("Error", icon="mdi:alert-circle") def error(self) -> str: """Human readable error description, see also :func:`error_code`.""" try: @@ -182,66 +187,80 @@ def error(self) -> str: return f"Definition missing for error {self.error_code}" @property + + @sensor("State", icon="mdi:robot-vacuum") def state(self) -> G1State: """Vacuum Status.""" return G1State(self.data["state"]) - @property + + @setting("Fan Speed", setter_name="set_fan_speed", choices=G1FanSpeed, icon="mdi:fan") def fan_speed(self) -> G1FanSpeed: """Fan Speed.""" return G1FanSpeed(self.data["fan_speed"]) - @property + + @sensor("Operating Mode", icon="mdi:robot-vacuum") def operating_mode(self) -> G1VacuumMode: """Operating Mode.""" return G1VacuumMode(self.data["operating_mode"]) - @property + + @sensor("Mop State", icon="mdi:robot-vacuum-variant") def mop_state(self) -> G1MopState: """Mop State.""" return G1MopState(self.data["mop_state"]) - @property + + @sensor("Water Level", icon="mdi:water") def water_level(self) -> G1WaterLevel: """Water Level.""" return G1WaterLevel(self.data["water_level"]) - @property + + @sensor("Main Brush Life Level", unit="%", icon="mdi:brush") def main_brush_life_level(self) -> int: """Main Brush Life Level in %.""" return self.data["main_brush_life_level"] - @property + + @sensor("Main Brush Time Left", icon="mdi:brush") def main_brush_time_left(self) -> timedelta: """Main Brush Remaining Time in Minutes.""" return timedelta(minutes=self.data["main_brush_time_left"]) - @property + + @sensor("Side Brush Life Level", unit="%", icon="mdi:brush") def side_brush_life_level(self) -> int: """Side Brush Life Level in %.""" return self.data["side_brush_life_level"] - @property + + @sensor("Side Brush Time Left", icon="mdi:brush") def side_brush_time_left(self) -> timedelta: """Side Brush Remaining Time in Minutes.""" return timedelta(minutes=self.data["side_brush_time_left"]) - @property + + @sensor("Filter Life Level", unit="%", icon="mdi:filter-outline") def filter_life_level(self) -> int: """Filter Life Level in %.""" return self.data["filter_life_level"] - @property + + @sensor("Filter Time Left", icon="mdi:filter-outline") def filter_time_left(self) -> timedelta: """Filter remaining time.""" return timedelta(minutes=self.data["filter_time_left"]) - @property + + @sensor("Clean Area", unit="cm²", icon="mdi:texture-box") def clean_area(self) -> int: """Clean Area in cm2.""" return self.data["clean_area"] - @property + + @sensor("Clean Time", icon="mdi:timer-outline") def clean_time(self) -> timedelta: """Clean time.""" return timedelta(minutes=self.data["clean_time"]) @@ -261,18 +280,21 @@ class G1CleaningSummary(DeviceStatus): def __init__(self, data) -> None: self.data = data - @property + + @sensor("Total Clean Count", icon="mdi:counter") def total_clean_count(self) -> int: """Total Number of Cleanings.""" return self.data["total_clean_count"] - @property + + @sensor("Total Clean Area", unit="m²", icon="mdi:texture-box") def total_clean_area(self) -> int: """Total Area Cleaned in m2.""" return self.data["total_clean_area"] - @property + + @sensor("Total Clean Time", icon="mdi:timer-outline") def total_clean_time(self) -> timedelta: """Total Cleaning Time.""" return timedelta(hours=self.data["total_clean_area"]) diff --git a/miio/integrations/mmgg/petwaterdispenser/status.py b/miio/integrations/mmgg/petwaterdispenser/status.py index 2704bc281..29c092b9f 100644 --- a/miio/integrations/mmgg/petwaterdispenser/status.py +++ b/miio/integrations/mmgg/petwaterdispenser/status.py @@ -2,6 +2,7 @@ from datetime import timedelta from typing import Any +from miio.devicestatus import sensor, setting from miio.miot_device import DeviceStatus @@ -34,36 +35,48 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property + @sensor(name="Sponge Filter Left Days", icon="mdi:filter") def sponge_filter_left_days(self) -> timedelta: """Filter life time remaining in days.""" return timedelta(days=self.data["filter_left_time"]) @property + @setting(name="Power", setter_name="on", icon="mdi:power") def is_on(self) -> bool: """True if device is on.""" return self.data["on"] @property + @setting( + name="Mode", + setter_name="set_mode", + icon="mdi:water-pump", + choices=OperatingMode, + ) def mode(self) -> OperatingMode: """OperatingMode.""" return OperatingMode(self.data["mode"]) @property + @setting(name="LED", setter_name="set_led", icon="mdi:led-outline") def is_led_on(self) -> bool: """True if enabled.""" return self.data["indicator_light"] @property + @sensor(name="Cotton Left Days", icon="mdi:filter") def cotton_left_days(self) -> timedelta: """Cotton filter life time remaining in days.""" return timedelta(days=self.data["cotton_left_time"]) @property + @sensor(name="Before Cleaning Days", icon="mdi:broom") def before_cleaning_days(self) -> timedelta: """Days before cleaning.""" return timedelta(days=self.data["remain_clean_time"]) @property + @sensor(name="No Water", icon="mdi:water-off") def is_no_water(self) -> bool: """True if there is no water left.""" if self.data["no_water_flag"]: @@ -71,31 +84,43 @@ def is_no_water(self) -> bool: return True @property + @sensor(name="No Water Duration", icon="mdi:water-off") def no_water_minutes(self) -> timedelta: """Minutes without water.""" return timedelta(minutes=self.data["no_water_time"]) @property + @sensor(name="Pump Blocked", icon="mdi:water-pump-off") def is_pump_blocked(self) -> bool: """True if pump is blocked.""" return self.data["pump_block_flag"] @property + @sensor(name="Lid Up", icon="mdi:archive-arrow-up") def is_lid_up(self) -> bool: """True if lid is up.""" return self.data["lid_up_flag"] @property + @setting( + name="Timezone", + setter_name="set_timezone", + icon="mdi:map-clock", + min_value=-12, + max_value=12, + ) def timezone(self) -> int: """Timezone from -12 to +12.""" return self.data["timezone"] @property + @setting(name="Location", setter_name="set_location", icon="mdi:map-marker") def location(self) -> str: """Device location string.""" return self.data["location"] @property + @sensor(name="Error Detected", icon="mdi:alert-circle") def is_error_detected(self) -> bool: """True if fault detected.""" return self.data["fault"] > 0 diff --git a/miio/integrations/nwt/dehumidifier/airdehumidifier.py b/miio/integrations/nwt/dehumidifier/airdehumidifier.py index 2885cb2b7..9a3b33b36 100644 --- a/miio/integrations/nwt/dehumidifier/airdehumidifier.py +++ b/miio/integrations/nwt/dehumidifier/airdehumidifier.py @@ -7,6 +7,7 @@ from miio import Device, DeviceError, DeviceException, DeviceInfo, DeviceStatus from miio.click_common import EnumType, command, format_output +from miio.devicestatus import sensor, setting _LOGGER = logging.getLogger(__name__) @@ -63,16 +64,24 @@ def __init__(self, data: dict[str, Any], device_info: DeviceInfo) -> None: self.device_info = device_info @property + @sensor("Power", icon="mdi:power") def power(self) -> str: """Power state.""" return self.data["on_off"] @property + @sensor("Is On", icon="mdi:power") def is_on(self) -> bool: """True if device is turned on.""" return self.power == "on" @property + @setting( + "Mode", + setter_name="set_mode", + choices=OperationMode, + icon="mdi:air-humidifier", + ) def mode(self) -> OperationMode: """Operation mode. @@ -81,6 +90,7 @@ def mode(self) -> OperationMode: return OperationMode(self.data["mode"]) @property + @sensor("Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") def temperature(self) -> float | None: """Current temperature, if available.""" if "temp" in self.data and self.data["temp"] is not None: @@ -88,26 +98,31 @@ def temperature(self) -> float | None: return None @property + @sensor("Humidity", unit="%", device_class="humidity", icon="mdi:water-percent") def humidity(self) -> int: """Current humidity.""" return self.data["humidity"] @property + @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") def buzzer(self) -> bool: """True if buzzer is turned on.""" return self.data["buzzer"] == "on" @property + @setting("LED", setter_name="set_led", icon="mdi:led-on") def led(self) -> bool: """LED brightness if available.""" return self.data["led"] == "on" @property + @setting("Child Lock", setter_name="set_child_lock", icon="mdi:lock") def child_lock(self) -> bool: """Return True if child lock is on.""" return self.data["child_lock"] == "on" @property + @setting( def target_humidity(self) -> int | None: """Target humiditiy. @@ -118,6 +133,7 @@ def target_humidity(self) -> int | None: return None @property + @setting( def fan_speed(self) -> FanSpeed | None: """Current fan speed.""" if "fan_speed" in self.data and self.data["fan_speed"] is not None: @@ -125,26 +141,31 @@ def fan_speed(self) -> FanSpeed | None: return None @property + @sensor("Tank Full", icon="mdi:cup-water") def tank_full(self) -> bool: """The remaining amount of water in percent.""" return self.data["tank_full"] == "on" @property + @sensor("Compressor Status", icon="mdi:air-conditioner") def compressor_status(self) -> bool: """Compressor status.""" return self.data["compressor_status"] == "on" @property + @sensor("Defrost Status", icon="mdi:snowflake-melt") def defrost_status(self) -> bool: """Defrost status.""" return self.data["defrost_status"] == "on" @property + @sensor("Fan St", icon="mdi:fan") def fan_st(self) -> int: """Fan st.""" return self.data["fan_st"] @property + @sensor("Alarm", icon="mdi:alarm-light") def alarm(self) -> str: """Alarm.""" return self.data["alarm"] diff --git a/miio/integrations/philips/light/ceil.py b/miio/integrations/philips/light/ceil.py index 36772694a..032ad42a5 100644 --- a/miio/integrations/philips/light/ceil.py +++ b/miio/integrations/philips/light/ceil.py @@ -6,6 +6,7 @@ from miio import Device, DeviceStatus from miio.click_common import command, format_output +from miio.devicestatus import sensor, setting _LOGGER = logging.getLogger(__name__) @@ -25,41 +26,77 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property + @sensor("Power", icon="mdi:power") def power(self) -> str: """Power state.""" return self.data["power"] @property + @sensor("Is On", icon="mdi:power") def is_on(self) -> bool: """True if the device is turned on.""" return self.power == "on" @property + @setting( + "Brightness", + setter_name="set_brightness", + icon="mdi:brightness-6", + unit="%", + min_value=1, + max_value=100, + step=1, + ) def brightness(self) -> int: """Current brightness.""" return self.data["bright"] @property + @setting( + "Scene", + setter_name="set_scene", + icon="mdi:palette", + min_value=1, + max_value=4, + step=1, + ) def scene(self) -> int: """Current fixed scene (brightness & colortemp).""" return self.data["snm"] @property + @setting( + "Delay Off Countdown", + setter_name="delay_off", + icon="mdi:timer", + device_class="duration", + unit="s", + ) def delay_off_countdown(self) -> int: """Countdown until turning off in seconds.""" return self.data["dv"] @property + @setting( + "Color Temperature", + setter_name="set_color_temperature", + icon="mdi:temperature-kelvin", + min_value=1, + max_value=100, + step=1, + ) def color_temperature(self) -> int: """Current color temperature.""" return self.data["cct"] @property + @sensor("Smart Night Light", icon="mdi:weather-night") def smart_night_light(self) -> bool: """Smart night mode state.""" return self.data["bl"] == 1 @property + @sensor("Automatic Color Temperature", icon="mdi:theme-light-dark") def automatic_color_temperature(self) -> bool: """Automatic color temperature state.""" return self.data["ac"] == 1 diff --git a/miio/integrations/philips/light/philips_bulb.py b/miio/integrations/philips/light/philips_bulb.py index d91d88cf5..afd729093 100644 --- a/miio/integrations/philips/light/philips_bulb.py +++ b/miio/integrations/philips/light/philips_bulb.py @@ -6,6 +6,7 @@ from miio import Device, DeviceStatus from miio.click_common import command, format_output +from miio.devicestatus import sensor, setting _LOGGER = logging.getLogger(__name__) @@ -37,14 +38,17 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property + @sensor("Power", icon="mdi:power") def power(self) -> str: return self.data["power"] @property + @setting("Power", setter_name="on", icon="mdi:power") def is_on(self) -> bool: return self.power == "on" @property + @setting("Brightness", setter_name="set_brightness", unit="%", icon="mdi:brightness-6") def brightness(self) -> int | None: if "bright" in self.data: return self.data["bright"] @@ -53,18 +57,21 @@ def brightness(self) -> int | None: return None @property + @setting("Color Temperature", setter_name="set_color_temperature", icon="mdi:palette") def color_temperature(self) -> int | None: if "cct" in self.data: return self.data["cct"] return None @property + @setting("Scene", setter_name="set_scene", icon="mdi:palette") def scene(self) -> int | None: if "snm" in self.data: return self.data["snm"] return None @property + @sensor("Delay Off Countdown", unit="s", icon="mdi:timer-outline", device_class="duration") def delay_off_countdown(self) -> int: return self.data["dv"] diff --git a/miio/integrations/philips/light/philips_eyecare.py b/miio/integrations/philips/light/philips_eyecare.py index 96ae3d461..9ab0f40ca 100644 --- a/miio/integrations/philips/light/philips_eyecare.py +++ b/miio/integrations/philips/light/philips_eyecare.py @@ -6,6 +6,7 @@ from miio import Device, DeviceStatus from miio.click_common import command, format_output +from miio.devicestatus import sensor, setting _LOGGER = logging.getLogger(__name__) @@ -20,51 +21,81 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property + @sensor("Power", icon="mdi:power") def power(self) -> str: """Power state.""" return self.data["power"] @property + @sensor("Is On", icon="mdi:power") def is_on(self) -> bool: """True if the device is turned on.""" return self.power == "on" @property + @setting( + "Brightness", + unit="%", + setter_name="set_brightness", + min_value=1, + max_value=100, + icon="mdi:brightness-6", + ) def brightness(self) -> int: """Current brightness of the primary light.""" return self.data["bright"] @property + @setting("Eye Fatigue Reminder", setter_name="reminder_on", icon="mdi:eye") def reminder(self) -> bool: """Indicates the eye fatigue notification is enabled or not.""" return self.data["notifystatus"] == "on" @property + @setting("Ambient Light", setter_name="ambient_on", icon="mdi:lightbulb-outline") def ambient(self) -> bool: """True if the ambient light (second light source) is on.""" return self.data["ambstatus"] == "on" @property + @setting( + "Ambient Brightness", + unit="%", + setter_name="set_ambient_brightness", + min_value=1, + max_value=100, + icon="mdi:brightness-6", + ) def ambient_brightness(self) -> int: """Brightness of the ambient light.""" return self.data["ambvalue"] @property + @setting("Eyecare Mode", setter_name="eyecare_on", icon="mdi:eye-check") def eyecare(self) -> bool: """True if the eyecare mode is on.""" return self.data["eyecare"] == "on" @property + @setting( + "Scene", + setter_name="set_scene", + min_value=1, + max_value=4, + icon="mdi:palette", + ) def scene(self) -> int: """Current fixed scene.""" return self.data["scene_num"] @property + @setting("Smart Night Light", setter_name="smart_night_light_on", icon="mdi:weather-night") def smart_night_light(self) -> bool: """True if the smart night light mode is on.""" return self.data["bls"] == "on" @property + @sensor("Delay Off Countdown", unit="min", icon="mdi:timer-sand", device_class="duration") def delay_off_countdown(self) -> int: """Countdown until turning off in minutes.""" return self.data["dvalue"] diff --git a/miio/integrations/philips/light/philips_moonlight.py b/miio/integrations/philips/light/philips_moonlight.py index 097e190aa..8163a0e6e 100644 --- a/miio/integrations/philips/light/philips_moonlight.py +++ b/miio/integrations/philips/light/philips_moonlight.py @@ -6,6 +6,7 @@ from miio import Device, DeviceStatus from miio.click_common import command, format_output +from miio.devicestatus import sensor, setting from miio.utils import int_to_rgb _LOGGER = logging.getLogger(__name__) @@ -23,31 +24,57 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property + @sensor(name="Power", icon="mdi:power") def power(self) -> str: return self.data["pow"] @property + @setting(name="Power", setter_name="on", icon="mdi:power") def is_on(self) -> bool: return self.power == "on" @property + @setting( + name="Brightness", + setter_name="set_brightness", + unit="%", + icon="mdi:brightness-6", + min_value=1, + max_value=100, + ) def brightness(self) -> int: return self.data["bri"] @property + @setting( + name="Color Temperature", + setter_name="set_color_temperature", + icon="mdi:thermometer", + min_value=1, + max_value=100, + ) def color_temperature(self) -> int: return self.data["cct"] @property + @setting(name="RGB", setter_name="set_rgb", icon="mdi:palette") def rgb(self) -> tuple[int, int, int]: """Return color in RGB.""" return int_to_rgb(int(self.data["rgb"])) @property + @setting( + name="Scene", + setter_name="set_scene", + icon="mdi:palette-swatch", + min_value=1, + max_value=6, + ) def scene(self) -> int: return self.data["snm"] @property + @sensor(name="Sleep Assistant", icon="mdi:sleep") def sleep_assistant(self) -> int: """Example values: @@ -59,24 +86,29 @@ def sleep_assistant(self) -> int: return self.data["sta"] @property + @sensor(name="Sleep Off Time", unit="s", icon="mdi:timer-off") def sleep_off_time(self) -> int: return self.data["spr"] @property + @sensor(name="Total Assistant Sleep Time", unit="s", icon="mdi:timer") def total_assistant_sleep_time(self) -> int: return self.data["spt"] @property + @sensor(name="Brand Sleep", icon="mdi:sleep") def brand_sleep(self) -> bool: # sp_sleep_open? return self.data["ms"] == 1 @property + @sensor(name="Brand", icon="mdi:watch") def brand(self) -> bool: # sp_xm_bracelet? return self.data["mb"] == 1 @property + @sensor(name="Wake Up Time", icon="mdi:alarm") def wake_up_time(self) -> list[int]: # Example: [weekdays?, hour, minute] return self.data["wkp"] diff --git a/miio/integrations/philips/light/philips_rwread.py b/miio/integrations/philips/light/philips_rwread.py index 3cb7de9c0..ee209d222 100644 --- a/miio/integrations/philips/light/philips_rwread.py +++ b/miio/integrations/philips/light/philips_rwread.py @@ -7,6 +7,7 @@ from miio import Device, DeviceStatus from miio.click_common import EnumType, command, format_output +from miio.devicestatus import sensor, setting _LOGGER = logging.getLogger(__name__) @@ -35,41 +36,75 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property + @sensor("Power", icon="mdi:power") def power(self) -> str: """Power state.""" return self.data["power"] @property + @sensor("Is On", icon="mdi:power") def is_on(self) -> bool: """True if the device is turned on.""" return self.power == "on" @property + @setting( + "Brightness", + setter_name="set_brightness", + icon="mdi:brightness-6", + unit="%", + min_value=1, + max_value=100, + step=1, + ) def brightness(self) -> int: """Current brightness.""" return self.data["bright"] @property + @setting( + "Delay Off Countdown", + setter_name="delay_off", + icon="mdi:timer", + device_class="duration", + unit="s", + ) def delay_off_countdown(self) -> int: """Countdown until turning off in seconds.""" return self.data["dv"] @property + @setting( + "Scene", + setter_name="set_scene", + icon="mdi:palette", + min_value=1, + max_value=4, + step=1, + ) def scene(self) -> int: """Current fixed scene.""" return self.data["snm"] @property + @setting("Motion Detection", setter_name="set_motion_detection", icon="mdi:motion-sensor") def motion_detection(self) -> bool: """True if motion detection is enabled.""" return self.data["flm"] == 1 @property + @setting( + "Motion Detection Sensitivity", + setter_name="set_motion_detection_sensitivity", + icon="mdi:signal-cellular-2", + choices=MotionDetectionSensitivity, + ) def motion_detection_sensitivity(self) -> MotionDetectionSensitivity: """The sensitivity of the motion detection.""" return MotionDetectionSensitivity(self.data["flmv"]) @property + @setting("Child Lock", setter_name="set_child_lock", icon="mdi:lock") def child_lock(self) -> bool: """True if child lock is enabled.""" return self.data["chl"] == 1 diff --git a/miio/integrations/pwzn/relay/pwzn_relay.py b/miio/integrations/pwzn/relay/pwzn_relay.py index 3380de57b..1f93b1d7a 100644 --- a/miio/integrations/pwzn/relay/pwzn_relay.py +++ b/miio/integrations/pwzn/relay/pwzn_relay.py @@ -6,6 +6,7 @@ from miio import Device, DeviceStatus from miio.click_common import command, format_output +from miio.devicestatus import sensor _LOGGER = logging.getLogger(__name__) @@ -70,6 +71,7 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property + @sensor("Relay State", icon="mdi:electric-switch") def relay_state(self) -> int | None: """Current relay state.""" if "relay_status" in self.data: @@ -77,6 +79,7 @@ def relay_state(self) -> int | None: return None @property + @sensor("Relay Names", icon="mdi:rename-box") def relay_names(self) -> dict[int, str]: def _extract_index_from_key(name) -> int: """extract the index from the variable.""" @@ -89,6 +92,7 @@ def _extract_index_from_key(name) -> int: } @property + @sensor("Active Relay Count", icon="mdi:counter") def on_count(self) -> int | None: """Number of on relay.""" if "on_count" in self.data: diff --git a/miio/integrations/roidmi/vacuum/roidmivacuum_miot.py b/miio/integrations/roidmi/vacuum/roidmivacuum_miot.py index 9e633f4c0..5a546c955 100644 --- a/miio/integrations/roidmi/vacuum/roidmivacuum_miot.py +++ b/miio/integrations/roidmi/vacuum/roidmivacuum_miot.py @@ -9,6 +9,7 @@ import click from miio.click_common import EnumType, command +from miio.devicestatus import sensor, setting from miio.integrations.roborock.vacuum.vacuumcontainers import ( # TODO: remove roborock import DNDStatus, ) @@ -222,18 +223,21 @@ def __init__(self, data): ] """ self.data = data - @property + + @sensor("Battery", unit="%", device_class="battery", icon="mdi:battery") def battery(self) -> int: """Remaining battery in percentage.""" return self.data["battery_level"] - @property + + @sensor("Error Code", icon="mdi:alert-circle") def error_code(self) -> int: """Error code as returned by the device.""" return int(self.data["error_code"]) - @property + + @sensor("Error", icon="mdi:alert-circle") def error(self) -> str: """Human readable error description, see also :func:`error_code`.""" try: @@ -242,6 +246,8 @@ def error(self) -> str: return f"Definition missing for error {self.error_code}" @property + + @sensor("Charging State", icon="mdi:battery-charging") def charging_state(self) -> ChargingState: """Charging state (Charging/Discharging)""" try: @@ -249,8 +255,9 @@ def charging_state(self) -> ChargingState: except ValueError: _LOGGER.error("Unknown ChargingStats (%s)", self.data["charging_state"]) return ChargingState.Unknown - @property + + @sensor("Sweep Mode", icon="mdi:robot-vacuum") def sweep_mode(self) -> SweepMode: """Sweep mode point/area/total etc.""" try: @@ -258,8 +265,9 @@ def sweep_mode(self) -> SweepMode: except ValueError: _LOGGER.error("Unknown SweepMode (%s)", self.data["sweep_mode"]) return SweepMode.Unknown - @property + + @setting("Fan Speed", setter_name="set_fanspeed", choices=FanSpeed, icon="mdi:fan") def fan_speed(self) -> FanSpeed: """Current fan speed.""" try: @@ -267,8 +275,9 @@ def fan_speed(self) -> FanSpeed: except ValueError: _LOGGER.error("Unknown FanSpeed (%s)", self.data["fanspeed_mode"]) return FanSpeed.Unknown - @property + + @setting("Sweep Type", setter_name="set_sweep_type", choices=SweepType, icon="mdi:robot-vacuum") def sweep_type(self) -> SweepType: """Current sweep type sweep/mop/sweep&mop.""" try: @@ -276,8 +285,9 @@ def sweep_type(self) -> SweepType: except ValueError: _LOGGER.error("Unknown SweepType (%s)", self.data["sweep_type"]) return SweepType.Unknown - @property + + @setting("Path Mode", setter_name="set_path_mode", choices=PathMode, icon="mdi:map-marker-path") def path_mode(self) -> PathMode: """Current path-mode: normal/y-mopping etc.""" try: @@ -285,21 +295,24 @@ def path_mode(self) -> PathMode: except ValueError: _LOGGER.error("Unknown PathMode (%s)", self.data["path_mode"]) return PathMode.Unknown - @property + + @sensor("Mop Attached", icon="mdi:robot-vacuum-variant") def is_mop_attached(self) -> bool: """Return True if mop is attached.""" return self.data["mop_present"] - @property + + @setting("Dust Collection Frequency", setter_name="set_dust_collection_frequency", min_value=0, max_value=3, step=1, icon="mdi:delete-variant") def dust_collection_frequency(self) -> int: """Frequency for emptying the dust bin. Example: 2 means the dust bin is emptied every second cleaning. """ return self.data["work_station_freq"] - @property + + @setting("Timing", setter_name="set_timing", icon="mdi:clock-outline") def timing(self) -> str: """Repeated cleaning. @@ -335,8 +348,9 @@ def timing(self) -> str: tz/tzs= time-zone """ return self.data["timing"] - @property + + @setting("Carpet Mode", setter_name="set_carpet_mode", icon="mdi:rug") def carpet_mode(self) -> bool: """Auto boost on carpet.""" return self.data["auto_boost"] @@ -361,13 +375,15 @@ def _seconds_to_components(val): end_minute=end[1], ) ) - @property + + @sensor("DND Status", icon="mdi:minus-circle") def dnd_status(self) -> DNDStatus: """Returns do-not-disturb status.""" return self._parse_forbid_mode(self.data["forbid_mode"]) - @property + + @setting("Water Level", setter_name="set_water_level", choices=WaterLevel, icon="mdi:water") def water_level(self) -> WaterLevel: """Get current water level.""" try: @@ -375,57 +391,67 @@ def water_level(self) -> WaterLevel: except ValueError: _LOGGER.error("Unknown WaterLevel (%s)", self.data["water_level"]) return WaterLevel.Unknown - @property + + @setting("Double Clean", setter_name="set_double_clean", icon="mdi:refresh") def double_clean(self) -> bool: """Is double clean enabled.""" return self.data["double_clean"] - @property + + @setting("LED", setter_name="set_led", icon="mdi:led-on") def led(self) -> bool: """Return True if led/display on vaccum is on.""" return self.data["led_switch"] - @property + + @setting("Lidar Collision Sensor", setter_name="set_lidar_collision_sensor", icon="mdi:radar") def is_lidar_collision_sensor(self) -> bool: """When ON, the robot will use lidar as the main detection sensor to help reduce collisions.""" return self.data["lidar_collision"] - @property + + @sensor("Station Key", icon="mdi:gesture-tap-button") def station_key(self) -> bool: """When ON: long press the display will turn on dust collection.""" return self.data["station_key"] - @property + + @setting("Station LED", setter_name="set_station_led", icon="mdi:led-on") def station_led(self) -> bool: """Return if station display is on.""" return self.data["station_led"] - @property + + @sensor("Current Audio", icon="mdi:account-voice") def current_audio(self) -> str: """Current voice setting. E.g. 'girl_en' """ return self.data["current_audio"] - @property + + @sensor("Clean Time", icon="mdi:timer-outline") def clean_time(self) -> timedelta: """Time used for cleaning (if finished, shows how long it took).""" return timedelta(seconds=self.data["clean_time_sec"]) - @property + + @sensor("Clean Area", unit="m²", icon="mdi:texture-box") def clean_area(self) -> int: """Cleaned area in m2.""" return self.data["clean_area"] - @property + + @sensor("State Code", icon="mdi:robot-vacuum") def state_code(self) -> int: """State code as returned by the device.""" return int(self.data["state"]) - @property + + @sensor("State", icon="mdi:robot-vacuum") def state(self) -> RoidmiState: """Human readable state description, see also :func:`state_code`.""" try: @@ -433,28 +459,33 @@ def state(self) -> RoidmiState: except ValueError: _LOGGER.error("Unknown RoidmiState (%s)", self.state_code) return RoidmiState.Unknown - @property + + @setting("Volume", setter_name="set_sound_volume", unit="%", min_value=0, max_value=100, step=1, icon="mdi:volume-high") def volume(self) -> int: """Return device sound volumen level.""" return self.data["volume"] - @property + + @setting("Muted", setter_name="set_sound_muted", icon="mdi:volume-off") def is_muted(self) -> bool: """True if device is muted.""" return bool(self.data["mute"]) - @property + + @sensor("Is Paused", icon="mdi:pause-circle") def is_paused(self) -> bool: """Return True if vacuum is paused.""" return self.state in [RoidmiState.Paused, RoidmiState.FindChargerPause] - @property + + @sensor("Is On", icon="mdi:robot-vacuum") def is_on(self) -> bool: """True if device is currently cleaning in any mode.""" return self.state == RoidmiState.Sweeping - @property + + @sensor("Got Error", icon="mdi:alert-circle") def got_error(self) -> bool: """True if an error has occurred.""" return self.error_code != 0 @@ -465,18 +496,21 @@ class RoidmiCleaningSummary(DeviceStatus): def __init__(self, data) -> None: self.data = data - @property + + @sensor("Total Duration", icon="mdi:timer-outline") def total_duration(self) -> timedelta: """Total cleaning duration.""" return timedelta(seconds=self.data["total_clean_time_sec"]) - @property + + @sensor("Total Area", unit="m²", icon="mdi:texture-box") def total_area(self) -> int: """Total cleaned area.""" return self.data["total_clean_areas"] - @property + + @sensor("Count", icon="mdi:counter") def count(self) -> int: """Number of cleaning runs.""" return self.data["clean_counts"] @@ -498,49 +532,57 @@ def _calcUsageTime( remaning_fraction = remaning_level / 100.0 original_total = renaning_time / remaning_fraction return original_total * (1 - remaning_fraction) - @property + + @sensor("Filter Usage", icon="mdi:filter-outline") def filter(self) -> timedelta: """Filter usage time.""" return self._calcUsageTime(self.filter_left, self.data["filter_life_level"]) - @property + + @sensor("Filter Left", icon="mdi:filter-outline") def filter_left(self) -> timedelta: """How long until the filter should be changed.""" return timedelta(minutes=self.data["filter_left_minutes"]) - @property + + @sensor("Main Brush Usage", icon="mdi:brush") def main_brush(self) -> timedelta: """Main brush usage time.""" return self._calcUsageTime( self.main_brush_left, self.data["main_brush_life_level"] ) - @property + + @sensor("Main Brush Left", icon="mdi:brush") def main_brush_left(self) -> timedelta: """How long until the main brush should be changed.""" return timedelta(minutes=self.data["main_brush_left_minutes"]) - @property + + @sensor("Side Brush Usage", icon="mdi:brush") def side_brush(self) -> timedelta: """Main brush usage time.""" return self._calcUsageTime( self.side_brush_left, self.data["side_brushes_life_level"] ) - @property + + @sensor("Side Brush Left", icon="mdi:brush") def side_brush_left(self) -> timedelta: """How long until the side brushes should be changed.""" return timedelta(minutes=self.data["side_brushes_left_minutes"]) - @property + + @sensor("Sensor Dirty", icon="mdi:eye-off") def sensor_dirty(self) -> timedelta: """Return time since last sensor clean.""" return self._calcUsageTime( self.sensor_dirty_left, self.data["sensor_dirty_remaning_level"] ) - @property + + @sensor("Sensor Dirty Left", icon="mdi:eye-off") def sensor_dirty_left(self) -> timedelta: """How long until the sensors should be cleaned.""" return timedelta(minutes=self.data["sensor_dirty_time_left_minutes"]) diff --git a/miio/integrations/shuii/humidifier/airhumidifier_jsq.py b/miio/integrations/shuii/humidifier/airhumidifier_jsq.py index d0364e32a..7457d3460 100644 --- a/miio/integrations/shuii/humidifier/airhumidifier_jsq.py +++ b/miio/integrations/shuii/humidifier/airhumidifier_jsq.py @@ -6,6 +6,7 @@ from miio import Device, DeviceStatus from miio.click_common import EnumType, command, format_output +from miio.devicestatus import sensor, setting _LOGGER = logging.getLogger(__name__) @@ -59,16 +60,24 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property + @sensor(name="Power", icon="mdi:power") def power(self) -> str: """Power state.""" return "on" if self.data["power"] == 1 else "off" @property + @setting(name="Power", setter_name="on", icon="mdi:power") def is_on(self) -> bool: """True if device is turned on.""" return self.power == "on" @property + @setting( + name="Mode", + setter_name="set_mode", + icon="mdi:fan", + choices=OperationMode, + ) def mode(self) -> OperationMode: """Operation mode. @@ -84,21 +93,30 @@ def mode(self) -> OperationMode: return mode @property + @sensor(name="Temperature", unit="C", device_class="temperature") def temperature(self) -> int: """Current temperature in degree celsius.""" return self.data["temperature"] @property + @sensor(name="Humidity", unit="%", device_class="humidity") def humidity(self) -> int: """Current humidity in percent.""" return self.data["humidity"] @property + @setting(name="Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") def buzzer(self) -> bool: """True if buzzer is turned on.""" return self.data["buzzer"] == 1 @property + @setting( + name="LED Brightness", + setter_name="set_led_brightness", + icon="mdi:brightness-6", + choices=LedBrightness, + ) def led_brightness(self) -> LedBrightness: """Buttons illumination Brightness level.""" try: @@ -110,26 +128,31 @@ def led_brightness(self) -> LedBrightness: return brightness @property + @setting(name="LED", setter_name="set_led", icon="mdi:led-outline") def led(self) -> bool: """True if LED is turned on.""" return self.led_brightness is not LedBrightness.Off @property + @setting(name="Child Lock", setter_name="set_child_lock", icon="mdi:lock") def child_lock(self) -> bool: """Return True if child lock is on.""" return self.data["child_lock"] == 1 @property + @sensor(name="No Water", icon="mdi:water-off") def no_water(self) -> bool: """True if the water tank is empty.""" return self.data["no_water"] == 1 @property + @sensor(name="Lid Opened", icon="mdi:cup-water") def lid_opened(self) -> bool: """True if the water tank is detached.""" return self.data["lid_opened"] == 1 @property + @sensor(name="Use Time", unit="s", icon="mdi:timer") def use_time(self) -> int | None: """How long the device has been active in seconds. diff --git a/miio/integrations/tinymu/toiletlid/toiletlid.py b/miio/integrations/tinymu/toiletlid/toiletlid.py index 2ebf0fb67..ad112210a 100644 --- a/miio/integrations/tinymu/toiletlid/toiletlid.py +++ b/miio/integrations/tinymu/toiletlid/toiletlid.py @@ -6,6 +6,7 @@ from miio import Device, DeviceStatus from miio.click_common import EnumType, command, format_output +from miio.devicestatus import sensor, setting _LOGGER = logging.getLogger(__name__) @@ -41,30 +42,36 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property + @sensor("Work State", icon="mdi:state-machine") def work_state(self) -> int: """Device state code.""" return self.data["work_state"] @property + @sensor("Work Mode", icon="mdi:toilet") def work_mode(self) -> ToiletlidOperatingMode: """Device working mode.""" return ToiletlidOperatingMode((self.work_state - 1) // 16) @property + @sensor("Power", icon="mdi:power") def is_on(self) -> bool: return self.work_state != 1 @property + @sensor("Filter Life Remaining", icon="mdi:filter") def filter_use_percentage(self) -> str: """Filter percentage of remaining life.""" return "{}%".format(self.data["filter_use_flux"]) @property + @sensor("Filter Remaining Time", unit="d", icon="mdi:filter-outline", device_class="duration") def filter_remaining_time(self) -> int: """Filter remaining life days.""" return self.data["filter_use_time"] @property + @setting("Ambient Light", setter_name="set_ambient_light", icon="mdi:lightbulb-variant", choices=AmbientLightColor) def ambient_light(self) -> str: """Ambient light color.""" return self.data["ambient_light"] diff --git a/miio/integrations/viomi/viomidishwasher/viomidishwasher.py b/miio/integrations/viomi/viomidishwasher/viomidishwasher.py index ff452d787..ba729cb10 100644 --- a/miio/integrations/viomi/viomidishwasher/viomidishwasher.py +++ b/miio/integrations/viomi/viomidishwasher/viomidishwasher.py @@ -8,6 +8,7 @@ from miio.click_common import EnumType, command, format_output from miio.device import Device, DeviceStatus +from miio.devicestatus import sensor, setting from miio.exceptions import DeviceException _LOGGER = logging.getLogger(__name__) @@ -103,6 +104,7 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property + @setting(name="Child Lock", setter_name="child_lock", icon="mdi:lock") def child_lock(self) -> bool: """Returns the child lock status of the device.""" value = self.data["child_lock"] @@ -112,6 +114,12 @@ def child_lock(self) -> bool: raise DeviceException(f"{value} is not a valid child lock status.") @property + @setting( + name="Program", + setter_name="start", + icon="mdi:dishwasher", + choices=Program, + ) def program(self) -> Program: """Returns the current selected program of the device.""" program = self.data["program"] @@ -122,12 +130,14 @@ def program(self) -> Program: return Program.Unknown @property + @sensor(name="Door Open", icon="mdi:door-open") def door_open(self) -> bool: """Returns True if the door is open.""" return bool(self.data["run_status"] & (1 << 7)) @property + @sensor(name="System Status Raw", icon="mdi:information-outline") def system_status_raw(self) -> int: """Returns the raw status number of the device. @@ -139,12 +149,14 @@ def system_status_raw(self) -> int: return self.data["run_status"] @property + @sensor(name="Status", icon="mdi:dishwasher") def status(self) -> MachineStatus: """Returns the machine status of the device.""" return MachineStatus(self.data["wash_status"]) @property + @sensor(name="Temperature", unit="C", device_class="temperature") def temperature(self) -> int: """Returns the temperature in degree Celsius as determined by the NTC thermistor.""" @@ -152,6 +164,7 @@ def temperature(self) -> int: return self.data["wash_temp"] @property + @setting(name="Power", setter_name="on", icon="mdi:power") def power(self) -> bool: """Returns the power status of the device.""" @@ -162,6 +175,7 @@ def power(self) -> bool: raise DeviceException(f"{value} is not a valid power status.") @property + @sensor(name="Time Left", icon="mdi:timer") def time_left(self) -> timedelta: """Returns the timedelta in seconds of time left of the current program. @@ -174,6 +188,7 @@ def time_left(self) -> timedelta: raise DeviceException(f"{value} is not a valid integer for time_left.") @property + @sensor(name="Schedule", icon="mdi:calendar-clock") def schedule(self) -> datetime | None: """Returns a datetime when the scheduled program should be finished. @@ -189,6 +204,7 @@ def schedule(self) -> datetime | None: ) @property + @setting(name="Air Refresh Interval", setter_name="airrefresh", icon="mdi:fan") def air_refresh_interval(self) -> int: """Returns an integer on how often the air in the device should be refreshed. @@ -203,6 +219,7 @@ def air_refresh_interval(self) -> int: raise DeviceException(f"{value} is not a valid integer for freshdry_interval.") @property + @sensor(name="Program Progress", icon="mdi:progress-check") def program_progress(self) -> ProgramStatus: """Returns the program status of the running program.""" value = self.data["wash_process"] @@ -213,6 +230,7 @@ def program_progress(self) -> ProgramStatus: return ProgramStatus.Unknown @property + @sensor(name="Errors", icon="mdi:alert-circle") def errors(self) -> list[SystemStatus]: """Returns list of errors if detected in the system.""" diff --git a/miio/integrations/xiaomi/aircondition/airconditioner_miot.py b/miio/integrations/xiaomi/aircondition/airconditioner_miot.py index 5b291cea3..20347a34e 100644 --- a/miio/integrations/xiaomi/aircondition/airconditioner_miot.py +++ b/miio/integrations/xiaomi/aircondition/airconditioner_miot.py @@ -7,6 +7,7 @@ from miio import DeviceStatus, MiotDevice from miio.click_common import EnumType, command, format_output +from miio.devicestatus import sensor, setting _LOGGER = logging.getLogger(__name__) @@ -78,23 +79,27 @@ def __init__(self, status: str): Only write 1 or 0 to it would start or abort the auto clean mode. """ self.status = [int(value) for value in status.split(",")] - @property + + @sensor("Cleaning", icon="mdi:broom") def cleaning(self) -> bool: return bool(self.status[0]) - @property + + @sensor("Progress", unit="%", icon="mdi:progress-check") def progress(self) -> int: return int(self.status[1]) - @property + + @sensor("Stage", icon="mdi:broom") def stage(self) -> str: try: return CLEANING_STAGES[self.status[2]] except KeyError: return "Unknown stage" - @property + + @sensor("Cancellable", icon="mdi:cancel") def cancellable(self) -> bool: return bool(self.status[3]) @@ -138,20 +143,24 @@ def __init__(self, status): Also, if the countdown minutes set to 0, the timer would be disabled. """ self.status = [int(value) for value in status.split(",")] - @property + + @sensor("Enabled", icon="mdi:timer") def enabled(self) -> bool: return bool(self.status[0]) - @property + + @sensor("Countdown", icon="mdi:timer-outline") def countdown(self) -> timedelta: return timedelta(minutes=self.status[1]) - @property + + @sensor("Power On", icon="mdi:power") def power_on(self) -> bool: return bool(self.status[2]) - @property + + @sensor("Time Left", icon="mdi:timer-outline") def time_left(self) -> timedelta: return timedelta(minutes=self.status[3]) @@ -184,93 +193,111 @@ def __init__(self, data: dict[str, Any]) -> None: """ self.data = data - @property + + @sensor("Is On", icon="mdi:power") def is_on(self) -> bool: """True if the device is turned on.""" return self.data["power"] - @property + + @sensor("Power", icon="mdi:power") def power(self) -> str: """Current power state.""" return "on" if self.is_on else "off" - @property + + @setting("Mode", setter_name="set_mode", choices=OperationMode, icon="mdi:air-conditioner") def mode(self) -> OperationMode: """Current operation mode.""" return OperationMode(self.data["mode"]) - @property + + @setting("Target Temperature", setter_name="set_target_temperature", unit="°C", min_value=16, max_value=31, step=1, device_class="temperature", icon="mdi:thermometer") def target_temperature(self) -> float: """Target temperature in Celsius.""" return self.data["target_temperature"] - @property + + @setting("ECO", setter_name="set_eco", icon="mdi:leaf") def eco(self) -> bool: """True if ECO mode is on.""" return self.data["eco"] - @property + + @setting("Heater", setter_name="set_heater", icon="mdi:radiator") def heater(self) -> bool: """True if aux heat mode is on.""" return self.data["heater"] - @property + + @setting("Dryer", setter_name="set_dryer", icon="mdi:water-off") def dryer(self) -> bool: """True if aux dryer mode is on.""" return self.data["dryer"] - @property + + @setting("Sleep Mode", setter_name="set_sleep_mode", icon="mdi:sleep") def sleep_mode(self) -> bool: """True if sleep mode is on.""" return self.data["sleep_mode"] - @property + + @setting("Fan Speed", setter_name="set_fan_speed", choices=FanSpeed, icon="mdi:fan") def fan_speed(self) -> FanSpeed: """Current Fan speed.""" return FanSpeed(self.data["fan_speed"]) - @property + + @setting("Vertical Swing", setter_name="set_vertical_swing", icon="mdi:arrow-up-down") def vertical_swing(self) -> bool: """True if vertical swing is on.""" return self.data["vertical_swing"] - @property + + @sensor("Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") def temperature(self) -> float: """Current ambient temperature in Celsius.""" return self.data["temperature"] - @property + + @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") def buzzer(self) -> bool: """True if buzzer is on.""" return self.data["buzzer"] - @property + + @setting("LED", setter_name="set_led", icon="mdi:led-on") def led(self) -> bool: """True if LED is on.""" return self.data["led"] - @property + + @sensor("Electricity", unit="kWh", device_class="energy", icon="mdi:flash") def electricity(self) -> float: """Power consumption accumulation in kWh.""" return self.data["electricity"] - @property + + @sensor("Clean", icon="mdi:broom") def clean(self) -> CleaningStatus: """Auto clean mode indicator.""" return CleaningStatus(self.data["clean"]) - @property + + @sensor("Total Running Duration", icon="mdi:timer-outline") def total_running_duration(self) -> timedelta: """Total running duration in hours.""" return timedelta(hours=self.data["running_duration"]) - @property + + @setting("Fan Speed Percent", setter_name="set_fan_speed_percent", unit="%", min_value=1, max_value=101, step=1, icon="mdi:fan") def fan_speed_percent(self) -> int: """Current fan speed in percent.""" return self.data["fan_speed_percent"] - @property + + @sensor("Timer", icon="mdi:timer") def timer(self) -> TimerStatus: """Countdown timer indicator.""" return TimerStatus(self.data["timer"]) diff --git a/miio/integrations/xiaomi/repeater/wifirepeater.py b/miio/integrations/xiaomi/repeater/wifirepeater.py index 670b64328..4fee888a8 100644 --- a/miio/integrations/xiaomi/repeater/wifirepeater.py +++ b/miio/integrations/xiaomi/repeater/wifirepeater.py @@ -4,6 +4,7 @@ from miio import Device, DeviceStatus from miio.click_common import command, format_output +from miio.devicestatus import sensor _LOGGER = logging.getLogger(__name__) @@ -25,11 +26,13 @@ def __init__(self, data): self.data = data @property + @sensor("Access Policy", icon="mdi:security") def access_policy(self) -> int: """Access policy of the associated stations.""" return self.data["sta"]["access_policy"] @property + @sensor("Associated Stations", icon="mdi:devices") def associated_stations(self) -> dict: """List of associated stations.""" return self.data["mat"] @@ -51,14 +54,17 @@ def __init__(self, data): self.data = data @property + @sensor("SSID", icon="mdi:wifi") def ssid(self) -> str: return self.data["ssid"] @property + @sensor("Password", icon="mdi:lock") def password(self) -> str: return self.data["pwd"] @property + @sensor("SSID Hidden", icon="mdi:wifi-off") def ssid_hidden(self) -> bool: return self.data["hidden"] == 1 diff --git a/miio/integrations/xiaomi/wifispeaker/wifispeaker.py b/miio/integrations/xiaomi/wifispeaker/wifispeaker.py index e37d11078..d2aeda925 100644 --- a/miio/integrations/xiaomi/wifispeaker/wifispeaker.py +++ b/miio/integrations/xiaomi/wifispeaker/wifispeaker.py @@ -5,6 +5,7 @@ from miio import Device, DeviceStatus from miio.click_common import command, format_output +from miio.devicestatus import sensor _LOGGER = logging.getLogger(__name__) @@ -46,46 +47,56 @@ def __init__(self, data): self.data = data @property + @sensor("Device Name", icon="mdi:speaker") def device_name(self) -> str: """Name of the device.""" return self.data["DeviceName"] @property + @sensor("Channel", icon="mdi:radio") def channel(self) -> str: """Name of the channel.""" return self.data["channel_title"] @property + @sensor("State", icon="mdi:play-circle") def state(self) -> PlayState: """State of the device, e.g. PLAYING.""" return PlayState(self.data["current_state"]) @property + @sensor("Hardware Version", icon="mdi:information-outline") def hardware_version(self) -> str: + """Hardware version.""" return self.data["hardware_version"] @property - def play_mode(self): + @sensor("Play Mode", icon="mdi:repeat") + def play_mode(self) -> str: """Play mode such as REPEAT_ALL.""" # note: this can be enumized when all values are known return self.data["play_mode"] @property + @sensor("Track Artist", icon="mdi:account-music") def track_artist(self) -> str: """Artist of the current track.""" return self.data["track_artist"] @property + @sensor("Track Title", icon="mdi:music-note") def track_title(self) -> str: """Title of the current track.""" return self.data["track_title"] @property + @sensor("Track Duration", icon="mdi:timer-music", device_class="duration") def track_duration(self) -> str: """Total duration of the current track.""" return self.data["track_duration"] @property + @sensor("Transport Channel", icon="mdi:radio") def transport_channel(self) -> TransportChannel: """Transport channel, e.g. PLAYLIST.""" return TransportChannel(self.data["transport_channel"]) diff --git a/miio/integrations/yeelight/dual_switch/yeelight_dual_switch.py b/miio/integrations/yeelight/dual_switch/yeelight_dual_switch.py index d95109b70..961a6859b 100644 --- a/miio/integrations/yeelight/dual_switch/yeelight_dual_switch.py +++ b/miio/integrations/yeelight/dual_switch/yeelight_dual_switch.py @@ -4,6 +4,7 @@ import click from miio.click_common import EnumType, command, format_output +from miio.devicestatus import sensor, setting from miio.miot_device import DeviceStatus, MiotDevice, MiotMapping @@ -61,46 +62,73 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property + @sensor("Switch 1 State", icon="mdi:toggle-switch") def switch_1_state(self) -> bool: """First switch state.""" return bool(self.data["switch_1_state"]) @property + @setting("Switch 1 Default State", setter_name="set_default_state", icon="mdi:toggle-switch-outline") def switch_1_default_state(self) -> bool: """First switch default state.""" return bool(self.data["switch_1_default_state"]) @property + @setting( + "Switch 1 Off Delay", + setter_name="set_switch_off_delay", + icon="mdi:timer", + device_class="duration", + unit="s", + min_value=-1, + max_value=43200, + step=1, + ) def switch_1_off_delay(self) -> int: """First switch off delay.""" return self.data["switch_1_off_delay"] @property + @sensor("Switch 2 State", icon="mdi:toggle-switch") def switch_2_state(self) -> bool: """Second switch state.""" return bool(self.data["switch_2_state"]) @property + @setting("Switch 2 Default State", setter_name="set_default_state", icon="mdi:toggle-switch-outline") def switch_2_default_state(self) -> bool: """Second switch default state.""" return bool(self.data["switch_2_default_state"]) @property + @setting( + "Switch 2 Off Delay", + setter_name="set_switch_off_delay", + icon="mdi:timer", + device_class="duration", + unit="s", + min_value=-1, + max_value=43200, + step=1, + ) def switch_2_off_delay(self) -> int: """Second switch off delay.""" return self.data["switch_2_off_delay"] @property + @setting("Interlock", setter_name="set_interlock", icon="mdi:lock-outline") def interlock(self) -> bool: """Interlock.""" return bool(self.data["interlock"]) @property + @setting("Flex Mode", setter_name="set_flex_mode", icon="mdi:shuffle-variant") def flex_mode(self) -> int: """Flex mode.""" return self.data["flex_mode"] @property + @sensor("RC List", icon="mdi:remote") def rc_list(self) -> str: """List of paired remote controls.""" return self.data["rc_list"] diff --git a/miio/integrations/yunmi/waterpurifier/waterpurifier.py b/miio/integrations/yunmi/waterpurifier/waterpurifier.py index 26abdf7e7..599b45130 100644 --- a/miio/integrations/yunmi/waterpurifier/waterpurifier.py +++ b/miio/integrations/yunmi/waterpurifier/waterpurifier.py @@ -3,6 +3,7 @@ from miio import Device, DeviceStatus from miio.click_common import command, format_output +from miio.devicestatus import sensor _LOGGER = logging.getLogger(__name__) @@ -14,78 +15,96 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property + @sensor("Power", icon="mdi:power") def power(self) -> str: return self.data["power"] @property + @sensor("Is On", icon="mdi:power") def is_on(self) -> bool: return self.power == "on" @property + @sensor("Mode", icon="mdi:water") def mode(self) -> str: """Current operation mode.""" return self.data["mode"] @property + @sensor("TDS", unit="ppm", icon="mdi:water-opacity") def tds(self) -> str: return self.data["tds"] @property + @sensor("Filter Life Remaining", unit="%", icon="mdi:filter") def filter_life_remaining(self) -> int: """Time until the filter should be changed.""" return self.data["filter1_life"] @property + @sensor("Filter State", icon="mdi:filter") def filter_state(self) -> str: return self.data["filter1_state"] @property + @sensor("Filter 2 Life Remaining", unit="%", icon="mdi:filter") def filter2_life_remaining(self) -> int: """Time until the filter should be changed.""" return self.data["filter_life"] @property + @sensor("Filter 2 State", icon="mdi:filter") def filter2_state(self) -> str: return self.data["filter_state"] @property + @sensor("Life", icon="mdi:clock-outline") def life(self) -> str: return self.data["life"] @property + @sensor("State", icon="mdi:information-outline") def state(self) -> str: return self.data["state"] @property + @sensor("Level", icon="mdi:water") def level(self) -> str: return self.data["level"] @property + @sensor("Volume", icon="mdi:cup-water") def volume(self) -> str: return self.data["volume"] @property + @sensor("Filter", icon="mdi:filter") def filter(self) -> str: return self.data["filter"] @property + @sensor("Usage", icon="mdi:chart-line") def usage(self) -> str: return self.data["usage"] @property + @sensor("Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") def temperature(self) -> str: return self.data["temperature"] @property + @sensor("UV Filter Life Remaining", unit="%", icon="mdi:filter") def uv_filter_life_remaining(self) -> int: """Time until the filter should be changed.""" return self.data["uv_life"] @property + @sensor("UV Filter State", icon="mdi:filter") def uv_filter_state(self) -> str: return self.data["uv_state"] @property + @sensor("Valve", icon="mdi:valve") def valve(self) -> str: return self.data["elecval_state"] diff --git a/miio/integrations/yunmi/waterpurifier/waterpurifier_yunmi.py b/miio/integrations/yunmi/waterpurifier/waterpurifier_yunmi.py index 9ae07e71a..be23cf308 100644 --- a/miio/integrations/yunmi/waterpurifier/waterpurifier_yunmi.py +++ b/miio/integrations/yunmi/waterpurifier/waterpurifier_yunmi.py @@ -4,6 +4,7 @@ from miio import Device, DeviceStatus from miio.click_common import command, format_output +from miio.devicestatus import sensor _LOGGER = logging.getLogger(__name__) @@ -93,8 +94,9 @@ def __init__(self, operation_status: int): for i in range(0, len(ERROR_DESCRIPTION)) if (1 << i) & operation_status ] - @property + + @sensor("Errors", icon="mdi:alert-circle") def errors(self) -> list: return self.err_list @@ -117,123 +119,147 @@ def __init__(self, data: dict[str, Any]) -> None: 'filter3_flow_used': 1440, 'filter3_life_used': 3313} """ self.data = data - @property + + @sensor("Operation Status", icon="mdi:information-outline") def operation_status(self) -> OperationStatus: """Current operation status.""" return OperationStatus(self.data["run_status"]) - @property + + @sensor("Filter 1 Life Total", icon="mdi:filter-outline") def filter1_life_total(self) -> timedelta: """Filter1 total available time in hours.""" return timedelta(hours=self.data["f1_totaltime"]) - @property + + @sensor("Filter 1 Life Used", icon="mdi:filter-outline") def filter1_life_used(self) -> timedelta: """Filter1 used time in hours.""" return timedelta(hours=self.data["f1_usedtime"]) - @property + + @sensor("Filter 1 Life Remaining", icon="mdi:filter-outline") def filter1_life_remaining(self) -> timedelta: """Filter1 remaining time in hours.""" return self.filter1_life_total - self.filter1_life_used - @property + + @sensor("Filter 1 Flow Total", unit="L", icon="mdi:water") def filter1_flow_total(self) -> int: """Filter1 total available flow in Metric Liter (L).""" return self.data["f1_totalflow"] - @property + + @sensor("Filter 1 Flow Used", unit="L", icon="mdi:water") def filter1_flow_used(self) -> int: """Filter1 used flow in Metric Liter (L).""" return self.data["f1_usedflow"] - @property + + @sensor("Filter 1 Flow Remaining", unit="L", icon="mdi:water") def filter1_flow_remaining(self) -> int: """Filter1 remaining flow in Metric Liter (L).""" return self.filter1_flow_total - self.filter1_flow_used - @property + + @sensor("Filter 2 Life Total", icon="mdi:filter-outline") def filter2_life_total(self) -> timedelta: """Filter2 total available time in hours.""" return timedelta(hours=self.data["f2_totaltime"]) - @property + + @sensor("Filter 2 Life Used", icon="mdi:filter-outline") def filter2_life_used(self) -> timedelta: """Filter2 used time in hours.""" return timedelta(hours=self.data["f2_usedtime"]) - @property + + @sensor("Filter 2 Life Remaining", icon="mdi:filter-outline") def filter2_life_remaining(self) -> timedelta: """Filter2 remaining time in hours.""" return self.filter2_life_total - self.filter2_life_used - @property + + @sensor("Filter 2 Flow Total", unit="L", icon="mdi:water") def filter2_flow_total(self) -> int: """Filter2 total available flow in Metric Liter (L).""" return self.data["f2_totalflow"] - @property + + @sensor("Filter 2 Flow Used", unit="L", icon="mdi:water") def filter2_flow_used(self) -> int: """Filter2 used flow in Metric Liter (L).""" return self.data["f2_usedflow"] - @property + + @sensor("Filter 2 Flow Remaining", unit="L", icon="mdi:water") def filter2_flow_remaining(self) -> int: """Filter2 remaining flow in Metric Liter (L).""" return self.filter2_flow_total - self.filter2_flow_used - @property + + @sensor("Filter 3 Life Total", icon="mdi:filter-outline") def filter3_life_total(self) -> timedelta: """Filter3 total available time in hours.""" return timedelta(hours=self.data["f3_totaltime"]) - @property + + @sensor("Filter 3 Life Used", icon="mdi:filter-outline") def filter3_life_used(self) -> timedelta: """Filter3 used time in hours.""" return timedelta(hours=self.data["f3_usedtime"]) - @property + + @sensor("Filter 3 Life Remaining", icon="mdi:filter-outline") def filter3_life_remaining(self) -> timedelta: """Filter3 remaining time in hours.""" return self.filter3_life_total - self.filter3_life_used - @property + + @sensor("Filter 3 Flow Total", unit="L", icon="mdi:water") def filter3_flow_total(self) -> int: """Filter3 total available flow in Metric Liter (L).""" return self.data["f3_totalflow"] - @property + + @sensor("Filter 3 Flow Used", unit="L", icon="mdi:water") def filter3_flow_used(self) -> int: """Filter3 used flow in Metric Liter (L).""" return self.data["f3_usedflow"] - @property + + @sensor("Filter 3 Flow Remaining", unit="L", icon="mdi:water") def filter3_flow_remaining(self) -> int: """Filter1 remaining flow in Metric Liter (L).""" return self.filter3_flow_total - self.filter3_flow_used - @property + + @sensor("TDS In", unit="ppm", icon="mdi:water-check") def tds_in(self) -> int: """TDS value of input water.""" return self.data["tds_in"] - @property + + @sensor("TDS Out", unit="ppm", icon="mdi:water-check") def tds_out(self) -> int: """TDS value of output water.""" return self.data["tds_out"] - @property + + @sensor("Rinse", icon="mdi:water-sync") def rinse(self) -> bool: """True if the device is rinsing.""" return self.data["rinse"] - @property + + @sensor("Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") def temperature(self) -> int: """Current water temperature in Celsius.""" return self.data["temperature"] - @property + + @sensor("TDS Warning Threshold", unit="ppm", icon="mdi:water-alert") def tds_warn_thd(self) -> int: """TDS warning threshold.""" return self.data["tds_warn_thd"] diff --git a/miio/integrations/zhimi/airpurifier/airfresh.py b/miio/integrations/zhimi/airpurifier/airfresh.py index 677ddcfc6..5e907a94f 100644 --- a/miio/integrations/zhimi/airpurifier/airfresh.py +++ b/miio/integrations/zhimi/airpurifier/airfresh.py @@ -7,6 +7,7 @@ from miio import Device, DeviceStatus from miio.click_common import EnumType, command, format_output +from miio.devicestatus import sensor, setting _LOGGER = logging.getLogger(__name__) @@ -90,46 +91,52 @@ def __init__(self, data: dict[str, Any], model: str) -> None: self.data = data self.model = model - @property + + @sensor("Power", icon="mdi:power") def power(self) -> str: """Power state.""" return self.data["power"] - @property + + @sensor("Is On", icon="mdi:power") def is_on(self) -> bool: """Return True if device is on.""" return self.power == "on" - @property + + @sensor("AQI", unit="μg/m³", icon="mdi:air-filter") def aqi(self) -> int: """Air quality index.""" return self.data["aqi"] - @property + + @sensor("Average AQI", unit="μg/m³", icon="mdi:air-filter") def average_aqi(self) -> int: """Average of the air quality index.""" return self.data["average_aqi"] - @property + + @sensor("CO2", unit="ppm", icon="mdi:molecule-co2", device_class="carbon_dioxide") def co2(self) -> int: """Carbon dioxide.""" return self.data["co2"] - @property + + @sensor("Humidity", unit="%", device_class="humidity", icon="mdi:water-percent") def humidity(self) -> int: """Current humidity.""" return self.data["humidity"] - @property + @setting("PTC", setter_name="set_ptc", icon="mdi:radiator") def ptc(self) -> bool | None: """Return True if PTC is on.""" if self.data["ptc_state"] is not None: return self.data["ptc_state"] == "on" return None - @property + @sensor("Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") def temperature(self) -> float | None: """Current temperature, if available.""" if self.data["temp_dec"] is not None: @@ -139,26 +146,28 @@ def temperature(self) -> float | None: return self.data["temp_dec"] / 10.0 return None - @property + @sensor("NTC Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") def ntc_temperature(self) -> float | None: """Current ntc temperature, if available.""" if self.data["ntcT"] is not None: return self.data["ntcT"] return None - @property + + @setting("Mode", setter_name="set_mode", choices=OperationMode, icon="mdi:fan") def mode(self) -> OperationMode: """Current operation mode.""" return OperationMode(self.data["mode"]) - @property + + @setting("LED", setter_name="set_led", icon="mdi:led-on") def led(self) -> bool: """Return True if LED is on.""" return self.data["led"] == "on" - @property + @setting("LED Brightness", setter_name="set_led_brightness", choices=LedBrightness, icon="mdi:brightness-6") def led_brightness(self) -> LedBrightness | None: """Brightness of the LED.""" if self.data["led_level"] is not None: @@ -171,41 +180,46 @@ def led_brightness(self) -> LedBrightness | None: return None return None - @property + @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") def buzzer(self) -> bool | None: """Return True if buzzer is on.""" if self.data["buzzer"] is not None: return self.data["buzzer"] == "on" return None - @property + + @setting("Child Lock", setter_name="set_child_lock", icon="mdi:lock") def child_lock(self) -> bool: """Return True if child lock is on.""" return self.data["child_lock"] == "on" - @property + + @sensor("Filter Life Remaining", unit="%", icon="mdi:filter-outline") def filter_life_remaining(self) -> int: """Time until the filter should be changed.""" return self.data["filter_life"] - @property + + @sensor("Filter Hours Used", unit="h", icon="mdi:filter-outline") def filter_hours_used(self) -> int: """How long the filter has been in use.""" return self.data["f1_hour_used"] - @property + + @sensor("Use Time", unit="s", icon="mdi:timer-sand") def use_time(self) -> int: """How long the device has been active in seconds.""" return self.data["use_time"] - @property + + @sensor("Motor Speed", unit="rpm", icon="mdi:fan") def motor_speed(self) -> int: """Speed of the motor.""" return self.data["motor1_speed"] - @property + @setting("Extra Features", setter_name="set_extra_features", icon="mdi:star") def extra_features(self) -> int | None: return self.data["app_extra"] diff --git a/miio/integrations/zhimi/airpurifier/airpurifier.py b/miio/integrations/zhimi/airpurifier/airpurifier.py index 286e258f6..b9d20712d 100644 --- a/miio/integrations/zhimi/airpurifier/airpurifier.py +++ b/miio/integrations/zhimi/airpurifier/airpurifier.py @@ -7,6 +7,7 @@ from miio import Device, DeviceStatus from miio.click_common import EnumType, command, format_output +from miio.devicestatus import sensor, setting from .airfilter_util import FilterType, FilterTypeUtil @@ -128,46 +129,52 @@ def __init__(self, data: dict[str, Any]) -> None: self.filter_type_util = FilterTypeUtil() self.data = data - @property + + @sensor("Power", icon="mdi:power") def power(self) -> str: """Power state.""" return self.data["power"] - @property + + @sensor("Is On", icon="mdi:power") def is_on(self) -> bool: """Return True if device is on.""" return self.power == "on" - @property + + @sensor("AQI", unit="μg/m³", icon="mdi:air-filter") def aqi(self) -> int: """Air quality index.""" return self.data["aqi"] - @property + + @sensor("Average AQI", unit="μg/m³", icon="mdi:air-filter") def average_aqi(self) -> int: """Average of the air quality index.""" return self.data["average_aqi"] - @property + + @sensor("Humidity", unit="%", device_class="humidity", icon="mdi:water-percent") def humidity(self) -> int: """Current humidity.""" return self.data["humidity"] - @property + @sensor("Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") def temperature(self) -> float | None: """Current temperature, if available.""" if self.data["temp_dec"] is not None: return self.data["temp_dec"] / 10.0 return None - @property + + @setting("Mode", setter_name="set_mode", choices=OperationMode, icon="mdi:air-purifier") def mode(self) -> OperationMode: """Current operation mode.""" return OperationMode(self.data["mode"]) - @property + @sensor("Sleep Mode", icon="mdi:sleep") def sleep_mode(self) -> SleepMode | None: """Operation mode of the sleep state. @@ -177,13 +184,14 @@ def sleep_mode(self) -> SleepMode | None: return SleepMode(self.data["sleep_mode"]) return None - @property + + @setting("LED", setter_name="set_led", icon="mdi:led-on") def led(self) -> bool: """Return True if LED is on.""" return self.data["led"] == "on" - @property + @setting("LED Brightness", setter_name="set_led_brightness", choices=LedBrightness, icon="mdi:brightness-6") def led_brightness(self) -> LedBrightness | None: """Brightness of the LED.""" if self.data["led_b"] is not None: @@ -193,119 +201,127 @@ def led_brightness(self) -> LedBrightness | None: return None return None - @property + @sensor("Illuminance", unit="lx", device_class="illuminance", icon="mdi:brightness-5") def illuminance(self) -> int | None: """Environment illuminance level in lux [0-200]. Sensor value is updated only when device is turned on. """ return self.data["bright"] - @property + @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") def buzzer(self) -> bool | None: """Return True if buzzer is on.""" if self.data["buzzer"] is not None: return self.data["buzzer"] == "on" return None - @property + + @setting("Child Lock", setter_name="set_child_lock", icon="mdi:lock") def child_lock(self) -> bool: """Return True if child lock is on.""" return self.data["child_lock"] == "on" - @property + + @setting("Favorite Level", setter_name="set_favorite_level", min_value=0, max_value=17, step=1, icon="mdi:star") def favorite_level(self) -> int: """Return favorite level, which is used if the mode is ``favorite``.""" # Favorite level used when the mode is `favorite`. return self.data["favorite_level"] - @property + + @sensor("Filter Life Remaining", unit="%", icon="mdi:filter-outline") def filter_life_remaining(self) -> int: """Time until the filter should be changed.""" return self.data["filter1_life"] - @property + + @sensor("Filter Hours Used", unit="h", icon="mdi:filter-outline") def filter_hours_used(self) -> int: """How long the filter has been in use.""" return self.data["f1_hour_used"] - @property + + @sensor("Use Time", unit="s", icon="mdi:timer-sand") def use_time(self) -> int: """How long the device has been active in seconds.""" return self.data["use_time"] - @property + + @sensor("Purify Volume", unit="m³", icon="mdi:air-purifier") def purify_volume(self) -> int: """The volume of purified air in cubic meter.""" return self.data["purify_volume"] - @property + + @sensor("Motor Speed", unit="rpm", icon="mdi:fan") def motor_speed(self) -> int: """Speed of the motor.""" return self.data["motor1_speed"] - @property + @sensor("Motor 2 Speed", unit="rpm", icon="mdi:fan") def motor2_speed(self) -> int | None: """Speed of the 2nd motor.""" return self.data["motor2_speed"] - @property + @setting("Volume", setter_name="set_volume", unit="%", min_value=0, max_value=100, step=1, icon="mdi:volume-high") def volume(self) -> int | None: """Volume of sound notifications [0-100].""" return self.data["volume"] - @property + @sensor("Filter RFID Product ID", icon="mdi:barcode") def filter_rfid_product_id(self) -> str | None: """RFID product ID of installed filter.""" return self.data["rfid_product_id"] - @property + @sensor("Filter RFID Tag", icon="mdi:barcode") def filter_rfid_tag(self) -> str | None: """RFID tag ID of installed filter.""" return self.data["rfid_tag"] - @property + @sensor("Filter Type", icon="mdi:filter-outline") def filter_type(self) -> FilterType | None: """Type of installed filter.""" return self.filter_type_util.determine_filter_type( self.filter_rfid_tag, self.filter_rfid_product_id ) - @property + + @setting("Learn Mode", setter_name="set_learn_mode", icon="mdi:school") def learn_mode(self) -> bool: """Return True if Learn Mode is enabled.""" return self.data["act_sleep"] == "single" - @property + @sensor("Sleep Time", unit="s", icon="mdi:sleep") def sleep_time(self) -> int | None: return self.data["sleep_time"] - @property + @sensor("Sleep Mode Learn Count", icon="mdi:counter") def sleep_mode_learn_count(self) -> int | None: return self.data["sleep_data_num"] - @property + @setting("Extra Features", setter_name="set_extra_features", icon="mdi:star") def extra_features(self) -> int | None: return self.data["app_extra"] - @property + @sensor("Turbo Mode Supported", icon="mdi:rocket") def turbo_mode_supported(self) -> bool | None: if self.data["app_extra"] is not None: return self.data["app_extra"] == 1 return None - @property + @setting("Auto Detect", setter_name="set_auto_detect", icon="mdi:eye") def auto_detect(self) -> bool | None: """Return True if auto detect is enabled.""" if self.data["act_det"] is not None: return self.data["act_det"] == "on" return None - @property + @sensor("Button Pressed", icon="mdi:gesture-tap-button") def button_pressed(self) -> str | None: """Last pressed button.""" return self.data["button_pressed"] diff --git a/miio/integrations/zhimi/fan/zhimi_miot.py b/miio/integrations/zhimi/fan/zhimi_miot.py index 6aee67559..62b29ae3a 100644 --- a/miio/integrations/zhimi/fan/zhimi_miot.py +++ b/miio/integrations/zhimi/fan/zhimi_miot.py @@ -5,6 +5,7 @@ from miio import DeviceException, DeviceStatus, MiotDevice from miio.click_common import EnumType, command, format_output +from miio.devicestatus import sensor, setting from miio.utils import deprecated @@ -80,18 +81,21 @@ def __init__(self, data: dict[str, Any]) -> None: {'code': 0, 'did': 'temperature', 'piid': 7, 'siid': 7, 'value': 26.4}, """ self.data = data - @property + + @setting("Ionizer", setter_name="set_ionizer", icon="mdi:atom") def ionizer(self) -> bool: """True if negative ions generation is enabled.""" return self.data["anion"] - @property + + @sensor("Battery Supported", icon="mdi:battery") def battery_supported(self) -> bool: """True if battery is supported.""" return self.data["battery_supported"] - @property + + @sensor("Buttons Pressed", icon="mdi:gesture-tap-button") def buttons_pressed(self) -> str: """What buttons on the fan are pressed now.""" code = self.data["buttons_pressed"] @@ -102,18 +106,21 @@ def buttons_pressed(self) -> str: if code == 2: return "Swing" return "Unknown" - @property + + @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") def buzzer(self) -> bool: """True if buzzer is turned on.""" return self.data["buzzer"] - @property + + @setting("Child Lock", setter_name="set_child_lock", icon="mdi:lock") def child_lock(self) -> bool: """True if child lock if on.""" return self.data["child_lock"] - @property + + @setting("Fan Level", setter_name="set_fan_speed", min_value=1, max_value=4, step=1, icon="mdi:fan") def fan_level(self) -> int: """Fan level (1-4).""" return self.data["fan_level"] @@ -123,63 +130,75 @@ def fan_level(self) -> int: def fan_speed(self) -> int: """Fan speed (1-100).""" return self.speed - @property + + @setting("Speed", setter_name="set_speed", min_value=1, max_value=100, step=1, unit="%", icon="mdi:fan") def speed(self) -> int: """Fan speed (1-100).""" return self.data["fan_speed"] - @property + + @sensor("Humidity", unit="%", device_class="humidity", icon="mdi:water-percent") def humidity(self) -> int: """Air humidity in percent.""" return self.data["humidity"] - @property + + @setting("LED Brightness", setter_name="set_led_brightness", min_value=0, max_value=100, step=1, unit="%", icon="mdi:brightness-6") def led_brightness(self) -> int: """LED brightness (1-100).""" return self.data["light"] - @property + + @setting("Mode", setter_name="set_mode", choices=OperationMode, icon="mdi:fan") def mode(self) -> OperationMode: """Operation mode (normal or nature).""" return OperationMode[OperationModeFanZA5(self.data["mode"]).name] - @property + + @sensor("Power", icon="mdi:power") def power(self) -> str: """Power state.""" return "on" if self.data["power"] else "off" - @property + + @sensor("Is On", icon="mdi:power") def is_on(self) -> bool: """True if device is currently on.""" return self.data["power"] - @property + + @setting("Delay Off Countdown", setter_name="delay_off", unit="s", icon="mdi:timer-off-outline") def delay_off_countdown(self) -> int: """Countdown until turning off in minutes.""" return self.data["power_off_time"] - @property + + @sensor("Power Supply Attached", icon="mdi:power-plug") def powersupply_attached(self) -> bool: """True is power supply is attached.""" return self.data["powersupply_attached"] - @property + + @sensor("Speed RPM", unit="rpm", icon="mdi:fan") def speed_rpm(self) -> int: """Fan rotations per minute.""" return self.data["speed_rpm"] - @property + + @setting("Oscillate", setter_name="set_oscillate", icon="mdi:arrow-left-right") def oscillate(self) -> bool: """True if oscillation is enabled.""" return self.data["swing_mode"] - @property + + @setting("Angle", setter_name="set_angle", icon="mdi:angle-acute") def angle(self) -> int: """Oscillation angle.""" return self.data["swing_mode_angle"] - @property + + @sensor("Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") def temperature(self) -> Any: """Air temperature (degree celsius).""" return self.data["temperature"] diff --git a/miio/integrations/zhimi/heater/heater.py b/miio/integrations/zhimi/heater/heater.py index 242875ffc..a77ef7c72 100644 --- a/miio/integrations/zhimi/heater/heater.py +++ b/miio/integrations/zhimi/heater/heater.py @@ -6,6 +6,7 @@ from miio import Device, DeviceStatus from miio.click_common import EnumType, command, format_output +from miio.devicestatus import sensor, setting _LOGGER = logging.getLogger(__name__) @@ -57,16 +58,19 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property + @sensor("Power", icon="mdi:power") def power(self) -> str: """Power state.""" return self.data["power"] @property + @sensor("Is On", icon="mdi:power") def is_on(self) -> bool: """True if device is currently on.""" return self.power == "on" @property + @sensor("Humidity", unit="%", icon="mdi:water-percent", device_class="humidity") def humidity(self) -> int | None: """Current humidity.""" if ( @@ -78,36 +82,56 @@ def humidity(self) -> int | None: return None @property + @sensor("Temperature", unit="°C", icon="mdi:thermometer", device_class="temperature") def temperature(self) -> float: """Current temperature.""" return self.data["temperature"] @property + @setting( + "Target Temperature", + unit="°C", + setter_name="set_target_temperature", + min_value=16, + max_value=32, + device_class="temperature", + icon="mdi:thermometer", + ) def target_temperature(self) -> int: """Target temperature.""" return self.data["target_temperature"] @property + @setting( + "Brightness", + setter_name="set_brightness", + choices=Brightness, + icon="mdi:brightness-6", + ) def brightness(self) -> Brightness: """Display brightness.""" return Brightness(self.data["brightness"]) @property + @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") def buzzer(self) -> bool: """True if buzzer is turned on.""" return self.data["buzzer"] in ["on", 1, 2] @property + @setting("Child Lock", setter_name="set_child_lock", icon="mdi:lock") def child_lock(self) -> bool: """True if child lock is on.""" return self.data["child_lock"] == "on" @property + @sensor("Use Time", unit="s", icon="mdi:timer", device_class="duration") def use_time(self) -> int: """How long the device has been active in seconds.""" return self.data["use_time"] @property + @sensor("Delay Off Countdown", unit="s", icon="mdi:timer-sand", device_class="duration") def delay_off_countdown(self) -> int | None: """Countdown until turning off in seconds.""" if "poweroff_time" in self.data and self.data["poweroff_time"] is not None: diff --git a/miio/integrations/zhimi/heater/heater_miot.py b/miio/integrations/zhimi/heater/heater_miot.py index d30b8ea29..0d76e6bdf 100644 --- a/miio/integrations/zhimi/heater/heater_miot.py +++ b/miio/integrations/zhimi/heater/heater_miot.py @@ -6,6 +6,7 @@ from miio import DeviceStatus, MiotDevice from miio.click_common import EnumType, command, format_output +from miio.devicestatus import sensor, setting _LOGGER = logging.getLogger(__name__) _MAPPINGS = { @@ -121,46 +122,68 @@ def __init__(self, data: dict[str, Any], model: str) -> None: self.model = model @property + @sensor("Power", icon="mdi:power") def power(self) -> str: """Power state.""" return "on" if self.is_on else "off" @property + @sensor("Is On", icon="mdi:power") def is_on(self) -> bool: """True if device is currently on.""" return self.data["power"] @property + @setting( + "Target Temperature", + unit="°C", + setter_name="set_target_temperature", + min_value=18, + max_value=28, + device_class="temperature", + icon="mdi:thermometer", + ) def target_temperature(self) -> int: """Target temperature.""" return self.data["target_temperature"] @property + @sensor("Delay Off Countdown", unit="s", icon="mdi:timer-sand", device_class="duration") def delay_off_countdown(self) -> int: """Countdown until turning off in seconds.""" return self.data["countdown_time"] @property + @sensor("Temperature", unit="°C", icon="mdi:thermometer", device_class="temperature") def temperature(self) -> float: """Current temperature.""" return self.data["temperature"] @property + @sensor("Relative Humidity", unit="%", icon="mdi:water-percent", device_class="humidity") def relative_humidity(self) -> int | None: """Current relative humidity.""" return self.data.get("relative_humidity") @property + @setting("Child Lock", setter_name="set_child_lock", icon="mdi:lock") def child_lock(self) -> bool: """True if child lock is on, False otherwise.""" return self.data["child_lock"] is True @property + @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") def buzzer(self) -> bool: """True if buzzer is turned on, False otherwise.""" return self.data["buzzer"] is True @property + @setting( + "LED Brightness", + setter_name="set_led_brightness", + choices=LedBrightness, + icon="mdi:brightness-6", + ) def led_brightness(self) -> LedBrightness: """LED indicator brightness.""" value = self.data["led_brightness"] diff --git a/miio/integrations/zimi/clock/alarmclock.py b/miio/integrations/zimi/clock/alarmclock.py index ac12ce7c3..004458ed9 100644 --- a/miio/integrations/zimi/clock/alarmclock.py +++ b/miio/integrations/zimi/clock/alarmclock.py @@ -5,6 +5,7 @@ from miio import Device, DeviceStatus from miio.click_common import EnumType, command +from miio.devicestatus import sensor class HourlySystem(enum.Enum): @@ -36,15 +37,18 @@ def __init__(self, data): self._end = data[2] @property + @sensor("Enabled", icon="mdi:alarm") def enabled(self) -> bool: return self._enabled @property - def start(self): + @sensor("Start Time", icon="mdi:clock-start") + def start(self) -> str: return self._start @property - def end(self): + @sensor("End Time", icon="mdi:clock-end") + def end(self) -> str: return self._end From afba8e36dbcaf424260cde237da3b82fe63daa49 Mon Sep 17 00:00:00 2001 From: Andrzej Pomirski Date: Fri, 27 Mar 2026 02:03:15 +0100 Subject: [PATCH 2/7] Fix decorator formatting with ruff format The decorator order was @property then @sensor/@setting (correct), but blank lines were misplaced between them. Run ruff format on all changed files to fix spacing. --- .../cgllc/airmonitor/airqualitymonitor.py | 1 + .../airmonitor/airqualitymonitor_miot.py | 4 +- .../chuangmi/camera/chuangmi_camera.py | 8 +- .../chuangmi/plug/chuangmi_plug.py | 4 +- miio/integrations/chunmi/cooker/cooker.py | 73 +++++----- .../deerma/humidifier/airhumidifier_jsqs.py | 1 + .../deerma/humidifier/airhumidifier_mjjsq.py | 1 + .../dmaker/airfresh/airfresh_t2017.py | 5 +- miio/integrations/dmaker/fan/fan.py | 4 +- miio/integrations/dmaker/fan/fan_miot.py | 4 +- .../dreame/vacuum/dreamevacuum_miot.py | 53 +++++--- .../acpartner/airconditioningcompanion.py | 1 + .../acpartner/airconditioningcompanionMCN.py | 3 + .../lumi/curtain/curtain_youpin.py | 14 +- miio/integrations/mijia/vacuum/g1vacuum.py | 43 +++--- .../nwt/dehumidifier/airdehumidifier.py | 1 + .../philips/light/philips_bulb.py | 9 +- .../philips/light/philips_eyecare.py | 13 +- .../philips/light/philips_rwread.py | 4 +- .../roidmi/vacuum/roidmivacuum_miot.py | 125 +++++++++++------- .../tinymu/toiletlid/toiletlid.py | 14 +- .../aircondition/airconditioner_miot.py | 88 +++++++----- .../dual_switch/yeelight_dual_switch.py | 12 +- .../yunmi/waterpurifier/waterpurifier.py | 4 +- .../waterpurifier/waterpurifier_yunmi.py | 54 ++++---- .../zhimi/airpurifier/airfresh.py | 29 ++-- .../zhimi/airpurifier/airpurifier.py | 47 ++++--- miio/integrations/zhimi/fan/zhimi_miot.py | 76 +++++++---- miio/integrations/zhimi/heater/heater.py | 5 +- miio/integrations/zhimi/heater/heater_miot.py | 9 +- 30 files changed, 454 insertions(+), 255 deletions(-) diff --git a/miio/integrations/cgllc/airmonitor/airqualitymonitor.py b/miio/integrations/cgllc/airmonitor/airqualitymonitor.py index 30d55c8aa..c179bcf53 100644 --- a/miio/integrations/cgllc/airmonitor/airqualitymonitor.py +++ b/miio/integrations/cgllc/airmonitor/airqualitymonitor.py @@ -148,6 +148,7 @@ def pm25(self) -> float | None: return self.data.get("pm25") @property + @sensor( @sensor("Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") def temperature(self) -> float | None: """Return temperature value (-10...50°C).""" diff --git a/miio/integrations/cgllc/airmonitor/airqualitymonitor_miot.py b/miio/integrations/cgllc/airmonitor/airqualitymonitor_miot.py index 796eca026..c57a2502e 100644 --- a/miio/integrations/cgllc/airmonitor/airqualitymonitor_miot.py +++ b/miio/integrations/cgllc/airmonitor/airqualitymonitor_miot.py @@ -126,7 +126,9 @@ def pm10(self) -> int: return self.data["pm10"] @property - @sensor("Temperature", unit="°C", icon="mdi:thermometer", device_class="temperature") + @sensor( + "Temperature", unit="°C", icon="mdi:thermometer", device_class="temperature" + ) def temperature(self) -> float: """Return temperature value (-30...100°C).""" return self.data["temperature"] diff --git a/miio/integrations/chuangmi/camera/chuangmi_camera.py b/miio/integrations/chuangmi/camera/chuangmi_camera.py index f314e48c3..5647a26b0 100644 --- a/miio/integrations/chuangmi/camera/chuangmi_camera.py +++ b/miio/integrations/chuangmi/camera/chuangmi_camera.py @@ -98,7 +98,9 @@ def power(self) -> bool: return self.data["power"] == "on" @property - @setting(name="Motion Record", setter_name="motion_record_on", icon="mdi:motion-sensor") + @setting( + name="Motion Record", setter_name="motion_record_on", icon="mdi:motion-sensor" + ) def motion_record(self) -> bool: """Motion record status.""" return self.data["motion_record"] == "on" @@ -122,7 +124,9 @@ def flip(self) -> bool: return self.data["flip"] == "on" @property - @setting(name="Improve Program", setter_name="improve_program_on", icon="mdi:chart-line") + @setting( + name="Improve Program", setter_name="improve_program_on", icon="mdi:chart-line" + ) def improve_program(self) -> bool: """Customer experience improvement program status.""" return self.data["improve_program"] == "on" diff --git a/miio/integrations/chuangmi/plug/chuangmi_plug.py b/miio/integrations/chuangmi/plug/chuangmi_plug.py index 2425f1d0d..27dac997a 100644 --- a/miio/integrations/chuangmi/plug/chuangmi_plug.py +++ b/miio/integrations/chuangmi/plug/chuangmi_plug.py @@ -63,7 +63,9 @@ def is_on(self) -> bool: return self.power @property - @sensor("Temperature", unit="°C", icon="mdi:thermometer", device_class="temperature") + @sensor( + "Temperature", unit="°C", icon="mdi:thermometer", device_class="temperature" + ) def temperature(self) -> int: return self.data["temperature"] diff --git a/miio/integrations/chunmi/cooker/cooker.py b/miio/integrations/chunmi/cooker/cooker.py index 64b6b7ad2..305950cd0 100644 --- a/miio/integrations/chunmi/cooker/cooker.py +++ b/miio/integrations/chunmi/cooker/cooker.py @@ -124,13 +124,13 @@ def __init__(self, data: str): self.data = [int(data[i : i + 2], 16) for i in range(0, len(data), 2)] else: self.data = [] - @property + @property @sensor("Temperatures", unit="°C", icon="mdi:thermometer") def temperatures(self) -> list[int]: return self.data - @property + @property @sensor("Raw", icon="mdi:code-string") def raw(self) -> str: return "".join([f"{value:02x}" for value in self.data]) @@ -165,33 +165,33 @@ def __init__(self, custom: str): Octet 11-16 (01 00 00 00 1d 1f): Meaning unknown """ self.custom = [int(custom[i : i + 2], 16) for i in range(0, len(custom), 2)] - @property + @property @sensor("Jingzhu Appointment", icon="mdi:clock-outline") def jingzhu_appointment(self) -> time: return time(hour=self.custom[0], minute=self.custom[1]) - @property + @property @sensor("Kuaizhu Appointment", icon="mdi:clock-outline") def kuaizhu_appointment(self) -> time: return time(hour=self.custom[2], minute=self.custom[3]) - @property + @property @sensor("Zhuzhou Appointment", icon="mdi:clock-outline") def zhuzhou_appointment(self) -> time: return time(hour=self.custom[4], minute=self.custom[5]) - @property + @property @sensor("Zhuzhou Cooking", icon="mdi:clock-outline") def zhuzhou_cooking(self) -> time: return time(hour=self.custom[6], minute=self.custom[7]) - @property + @property @sensor("Favorite Appointment", icon="mdi:clock-outline") def favorite_appointment(self) -> time: return time(hour=self.custom[8], minute=self.custom[9]) - @property + @property @sensor("Favorite Cooking", icon="mdi:clock-outline") def favorite_cooking(self) -> time: return time(hour=self.custom[10], minute=self.custom[11]) @@ -214,8 +214,8 @@ def __init__(self, stage: str): Octet 5 (ff): Meaning unknown. """ self.stage = stage - @property + @property @sensor("State", icon="mdi:pot-steam") def state(self) -> int: """ @@ -225,18 +225,18 @@ def state(self) -> int: 12: Cooking finished """ return int(self.stage[0:2], 16) - @property + @property @sensor("Rice ID", icon="mdi:rice") def rice_id(self) -> int: return int(self.stage[2:6], 16) - @property + @property @sensor("Taste", icon="mdi:food-variant") def taste(self) -> int: return int(self.stage[6:8], 16) - @property + @property @sensor("Taste Phase", icon="mdi:food-variant") def taste_phase(self) -> int: phase = int(self.taste / 33) @@ -244,24 +244,24 @@ def taste_phase(self) -> int: if phase > 2: return 2 return phase - @property + @property @sensor("Name", icon="mdi:label") def name(self) -> str: try: return COOKING_STAGES[self.state]["name"] except KeyError: return "Unknown stage" - @property + @property @sensor("Description", icon="mdi:text") def description(self) -> str: try: return COOKING_STAGES[self.state]["description"] except KeyError: return "" - @property + @property @sensor("Raw", icon="mdi:code-string") def raw(self) -> str: return self.stage @@ -283,8 +283,8 @@ def __init__(self, timeouts: str | None = None): self.timeouts = [ int(timeouts[i : i + 2], 16) for i in range(0, len(timeouts), 2) ] - @property + @property @sensor("LED Off Timeout", unit="s", icon="mdi:led-off") def led_off(self) -> int: return self.timeouts[0] @@ -292,8 +292,8 @@ def led_off(self) -> int: @led_off.setter def led_off(self, delay: int): self.timeouts[0] = delay - @property + @property @sensor("Lid Open Timeout", unit="s", icon="mdi:pot-steam-outline") def lid_open(self) -> int: return self.timeouts[1] @@ -301,8 +301,8 @@ def lid_open(self) -> int: @lid_open.setter def lid_open(self, timeout: int): self.timeouts[1] = timeout - @property + @property @sensor("Lid Open Warning Timeout", unit="s", icon="mdi:alert") def lid_open_warning(self) -> int: return self.timeouts[2] @@ -341,8 +341,8 @@ def __init__(self, settings: str | None = None): self._settings = [ int(settings[i : i + 2], 16) for i in range(0, len(settings), 2) ] - @property + @property @sensor("Pressure Supported", icon="mdi:gauge") def pressure_supported(self) -> bool: return self._settings[0] & 1 != 0 @@ -353,8 +353,8 @@ def pressure_supported(self, supported: bool): self._settings[0] |= 1 else: self._settings[0] &= 254 - @property + @property @sensor("LED On", icon="mdi:led-on") def led_on(self) -> bool: return self._settings[0] & 2 != 0 @@ -365,8 +365,8 @@ def led_on(self, on: bool): self._settings[0] |= 2 else: self._settings[0] &= 253 - @property + @property @sensor("Auto Keep Warm", icon="mdi:pot-steam") def auto_keep_warm(self) -> bool: return self._settings[0] & 4 != 0 @@ -377,8 +377,8 @@ def auto_keep_warm(self, keep_warm: bool): self._settings[0] |= 4 else: self._settings[0] &= 251 - @property + @property @sensor("Lid Open Warning", icon="mdi:alert") def lid_open_warning(self) -> bool: return self._settings[0] & 8 != 0 @@ -389,8 +389,8 @@ def lid_open_warning(self, alarm: bool): self._settings[0] |= 8 else: self._settings[0] &= 247 - @property + @property @sensor("Lid Open Warning Delayed", icon="mdi:alert-outline") def lid_open_warning_delayed(self) -> bool: return self._settings[0] & 16 != 0 @@ -401,8 +401,8 @@ def lid_open_warning_delayed(self, alarm: bool): self._settings[0] |= 16 else: self._settings[0] &= 239 - @property + @property @sensor("Jingzhu Auto Keep Warm", icon="mdi:pot-steam") def jingzhu_auto_keep_warm(self) -> bool: return self._settings[1] & 1 != 0 @@ -413,8 +413,8 @@ def jingzhu_auto_keep_warm(self, auto_keep_warm: bool): self._settings[1] |= 1 else: self._settings[1] &= 254 - @property + @property @sensor("Kuaizhu Auto Keep Warm", icon="mdi:pot-steam") def kuaizhu_auto_keep_warm(self) -> bool: return self._settings[1] & 2 != 0 @@ -425,8 +425,8 @@ def kuaizhu_auto_keep_warm(self, auto_keep_warm: bool): self._settings[1] |= 2 else: self._settings[1] &= 253 - @property + @property @sensor("Zhuzhou Auto Keep Warm", icon="mdi:pot-steam") def zhuzhou_auto_keep_warm(self) -> bool: return self._settings[1] & 4 != 0 @@ -437,8 +437,8 @@ def zhuzhou_auto_keep_warm(self, auto_keep_warm: bool): self._settings[1] |= 4 else: self._settings[1] &= 251 - @property + @property @sensor("Favorite Auto Keep Warm", icon="mdi:pot-steam") def favorite_auto_keep_warm(self) -> bool: return self._settings[1] & 8 != 0 @@ -496,14 +496,14 @@ def __init__(self, data): meal is ready: ['autokeepwarm', '0001', '1000000000', '031e0b23031e', '1', '750', '60', '0207', '05040f', '00030017', '0100', 'ffffffffffff011effff01000000535d'] """ self.data = data - @property + @property @sensor("Mode", icon="mdi:pot-steam") def mode(self) -> OperationMode: """Current operation mode.""" return OperationMode(self.data["func"]) - @property + @property @sensor("Menu", icon="mdi:book-open-variant") def menu(self) -> int: """Selected recipe id.""" @@ -517,6 +517,7 @@ def stage(self) -> CookingStage | None: return CookingStage(stage) return None + @sensor( @property @sensor("Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") def temperature(self) -> int | None: @@ -542,8 +543,8 @@ def start_time(self) -> time | None: return time(hour=int(value[4:6], 16), minute=int(value[6:8], 16)) return None - @property + @property @sensor("Remaining", unit="min", icon="mdi:timer-outline") def remaining(self) -> int: """Remaining minutes of the cooking process.""" @@ -558,38 +559,38 @@ def cooking_delayed(self) -> int | None: return delay return None - @property + @property @sensor("Duration", unit="min", icon="mdi:timer-outline") def duration(self) -> int: """Duration of the cooking process.""" return int(self.data["t_cook"]) - @property + @property @sensor("Cooker Settings", icon="mdi:cog") def cooker_settings(self) -> CookerSettings: """Settings of the cooker.""" return CookerSettings(self.data["setting"]) - @property + @property @sensor("Interaction Timeouts", icon="mdi:timer-cog-outline") def interaction_timeouts(self) -> InteractionTimeouts: """Interaction timeouts.""" return InteractionTimeouts(self.data["delay"]) - @property + @property @sensor("Hardware Version", icon="mdi:chip") def hardware_version(self) -> int: """Hardware version.""" return int(self.data["version"][0:4], 16) - @property + @property @sensor("Firmware Version", icon="mdi:update") def firmware_version(self) -> int: """Firmware version.""" return int(self.data["version"][4:8], 16) - @property + @property @sensor("Favorite", icon="mdi:star") def favorite(self) -> int: """Favored recipe id. diff --git a/miio/integrations/deerma/humidifier/airhumidifier_jsqs.py b/miio/integrations/deerma/humidifier/airhumidifier_jsqs.py index 99f58cb06..e2d6095e5 100644 --- a/miio/integrations/deerma/humidifier/airhumidifier_jsqs.py +++ b/miio/integrations/deerma/humidifier/airhumidifier_jsqs.py @@ -156,6 +156,7 @@ def water_shortage_fault(self) -> bool | None: return self.data.get("water_shortage_fault") @property + @setting( @setting(name="Overwet Protect", setter_name="set_overwet_protect", icon="mdi:shield-check") def overwet_protect(self) -> bool | None: """Return True if overwet mode is active.""" diff --git a/miio/integrations/deerma/humidifier/airhumidifier_mjjsq.py b/miio/integrations/deerma/humidifier/airhumidifier_mjjsq.py index fe7655a33..d2bce51bd 100644 --- a/miio/integrations/deerma/humidifier/airhumidifier_mjjsq.py +++ b/miio/integrations/deerma/humidifier/airhumidifier_mjjsq.py @@ -131,6 +131,7 @@ def water_tank_detached(self) -> bool: return self.data["watertankstatus"] == 0 @property + @setting( @setting(name="Wet Protection", setter_name="set_wet_protection", icon="mdi:shield-check") def wet_protection(self) -> bool | None: """True if wet protection is enabled.""" diff --git a/miio/integrations/dmaker/airfresh/airfresh_t2017.py b/miio/integrations/dmaker/airfresh/airfresh_t2017.py index 4d66826eb..2e843086f 100644 --- a/miio/integrations/dmaker/airfresh/airfresh_t2017.py +++ b/miio/integrations/dmaker/airfresh/airfresh_t2017.py @@ -151,7 +151,9 @@ def co2(self) -> int: return self.data["co2"] @property - @sensor("Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") + @sensor( + "Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer" + ) def temperature(self) -> int: """Current temperature in degree celsions.""" return self.data["temperature_outside"] @@ -205,6 +207,7 @@ def ptc(self) -> bool: return self.data["ptc_on"] @property + @setting( @setting("PTC Level", setter_name="set_ptc_level", choices=PtcLevel, icon="mdi:radiator") def ptc_level(self) -> PtcLevel | None: """PTC level.""" diff --git a/miio/integrations/dmaker/fan/fan.py b/miio/integrations/dmaker/fan/fan.py index ca803d143..0f419c2d1 100644 --- a/miio/integrations/dmaker/fan/fan.py +++ b/miio/integrations/dmaker/fan/fan.py @@ -105,7 +105,9 @@ def angle(self) -> int: return self.data["roll_angle"] @property - @sensor("Delay Off Countdown", unit="s", icon="mdi:timer-sand", device_class="duration") + @sensor( + "Delay Off Countdown", unit="s", icon="mdi:timer-sand", device_class="duration" + ) def delay_off_countdown(self) -> int: """Countdown until turning off in seconds.""" return self.data["time_off"] diff --git a/miio/integrations/dmaker/fan/fan_miot.py b/miio/integrations/dmaker/fan/fan_miot.py index 90adbcf59..d76afd777 100644 --- a/miio/integrations/dmaker/fan/fan_miot.py +++ b/miio/integrations/dmaker/fan/fan_miot.py @@ -210,7 +210,9 @@ def mode(self) -> OperationMode: return OperationMode[OperationModeMiot(self.data["mode"]).name] @property - @setting("Speed", setter_name="set_speed", min_value=0, max_value=100, icon="mdi:fan") + @setting( + "Speed", setter_name="set_speed", min_value=0, max_value=100, icon="mdi:fan" + ) def speed(self) -> int: """Speed of the motor.""" return self.data["fan_speed"] diff --git a/miio/integrations/dreame/vacuum/dreamevacuum_miot.py b/miio/integrations/dreame/vacuum/dreamevacuum_miot.py index 6b7d13ca3..e70eb4b7c 100644 --- a/miio/integrations/dreame/vacuum/dreamevacuum_miot.py +++ b/miio/integrations/dreame/vacuum/dreamevacuum_miot.py @@ -304,38 +304,38 @@ class DreameVacuumStatus(DeviceStatusContainer): def __init__(self, data, model): self.data = data self.model = model - @property + @property @sensor("Battery Level", unit="%", device_class="battery", icon="mdi:battery") def battery_level(self) -> str: return self.data["battery_level"] - @property + @property @sensor("Brush Left Time", unit="h", icon="mdi:brush") def brush_left_time(self) -> str: return self.data["brush_left_time"] - @property + @property @sensor("Side Brush Left Time", unit="h", icon="mdi:brush") def brush_left_time2(self) -> str: return self.data["brush_left_time2"] - @property + @property @sensor("Side Brush Life Level", unit="%", icon="mdi:brush") def brush_life_level2(self) -> str: return self.data["brush_life_level2"] - @property + @property @sensor("Brush Life Level", unit="%", icon="mdi:brush") def brush_life_level(self) -> str: return self.data["brush_life_level"] - @property + @property @sensor("Filter Left Time", unit="h", icon="mdi:filter-outline") def filter_left_time(self) -> str: return self.data["filter_left_time"] - @property + @property @sensor("Filter Life Level", unit="%", icon="mdi:filter-outline") def filter_life_level(self) -> str: return self.data["filter_life_level"] @@ -371,73 +371,81 @@ def device_status(self) -> DeviceStatus | None: except TypeError: _LOGGER.error("Unknown DeviceStatus (%s)", self.data["device_status"]) return None - @property + @property @sensor("Timer Enable", icon="mdi:timer") def timer_enable(self) -> str: return self.data["timer_enable"] - @property + @property @sensor("Start Time", icon="mdi:clock-start") def start_time(self) -> str: return self.data["start_time"] - @property + @property @sensor("Stop Time", icon="mdi:clock-end") def stop_time(self) -> str: return self.data["stop_time"] - @property + @property @sensor("Map View", icon="mdi:map") def map_view(self) -> str: return self.data["map_view"] - @property - @setting("Volume", setter_name="set_sound_volume", unit="%", min_value=0, max_value=100, step=1, icon="mdi:volume-high") + @property + @setting( + "Volume", + setter_name="set_sound_volume", + unit="%", + min_value=0, + max_value=100, + step=1, + icon="mdi:volume-high", + ) def volume(self) -> str: return self.data["volume"] - @property + @property @sensor("Voice Package", icon="mdi:account-voice") def voice_package(self) -> str: return self.data["voice_package"] - @property + @property @sensor("Timezone", icon="mdi:earth") def timezone(self) -> str: return self.data["timezone"] - @property + @property @sensor("Cleaning Time", unit="min", icon="mdi:timer-outline") def cleaning_time(self) -> str: return self.data["cleaning_time"] - @property + @property @sensor("Cleaning Area", unit="m²", icon="mdi:texture-box") def cleaning_area(self) -> str: return self.data["cleaning_area"] - @property + @property @sensor("First Clean Time", icon="mdi:clock-outline") def first_clean_time(self) -> str: return self.data["first_clean_time"] - @property + @property @sensor("Total Clean Time", unit="min", icon="mdi:timer-outline") def total_clean_time(self) -> str: return self.data["total_clean_time"] - @property + @property @sensor("Total Clean Times", icon="mdi:counter") def total_clean_times(self) -> str: return self.data["total_clean_times"] - @property + @property @sensor("Total Clean Area", unit="m²", icon="mdi:texture-box") def total_clean_area(self) -> str: return self.data["total_clean_area"] - @property + @property @setting("Cleaning Mode", setter_name="set_fan_speed", icon="mdi:fan") def cleaning_mode(self): cleaning_mode = self.data["cleaning_mode"] @@ -466,6 +474,7 @@ def life_brush_main(self) -> str | None: # TODO: get/set water flow for Dreame 1C @property + @setting( @setting("Water Flow", setter_name="set_waterflow", choices=WaterFlow, icon="mdi:water") def water_flow(self) -> WaterFlow | None: try: diff --git a/miio/integrations/lumi/acpartner/airconditioningcompanion.py b/miio/integrations/lumi/acpartner/airconditioningcompanion.py index ac4eed78f..8d49e748d 100644 --- a/miio/integrations/lumi/acpartner/airconditioningcompanion.py +++ b/miio/integrations/lumi/acpartner/airconditioningcompanion.py @@ -196,6 +196,7 @@ def is_on(self) -> bool: return self.power == "on" @property + @sensor( @sensor("Target Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") def target_temperature(self) -> int | None: """Target temperature.""" diff --git a/miio/integrations/lumi/acpartner/airconditioningcompanionMCN.py b/miio/integrations/lumi/acpartner/airconditioningcompanionMCN.py index 59edff359..f3ade1a10 100644 --- a/miio/integrations/lumi/acpartner/airconditioningcompanionMCN.py +++ b/miio/integrations/lumi/acpartner/airconditioningcompanionMCN.py @@ -63,6 +63,7 @@ def is_on(self) -> bool: return self.power == "on" @property + @setting( @setting("Mode", setter_name="send_command", icon="mdi:air-conditioner", choices=OperationMode) def mode(self) -> OperationMode | None: """Current operation mode.""" @@ -73,6 +74,7 @@ def mode(self) -> OperationMode | None: return None @property + @setting( @setting("Target Temperature", setter_name="send_command", unit="°C", icon="mdi:thermometer", device_class="temperature") def target_temperature(self) -> int | None: """Target temperature.""" @@ -92,6 +94,7 @@ def fan_speed(self) -> FanSpeed | None: return None @property + @setting( @setting("Swing Mode", setter_name="send_command", icon="mdi:arrow-oscillating", choices=SwingMode) def swing_mode(self) -> SwingMode | None: """Current swing mode.""" diff --git a/miio/integrations/lumi/curtain/curtain_youpin.py b/miio/integrations/lumi/curtain/curtain_youpin.py index d34020338..cb85fc9d6 100644 --- a/miio/integrations/lumi/curtain/curtain_youpin.py +++ b/miio/integrations/lumi/curtain/curtain_youpin.py @@ -80,7 +80,9 @@ def status(self) -> Status: return Status(self.data["status"]) @property - @setting("Manual Enabled", setter_name="set_manual_enabled", icon="mdi:hand-back-left") + @setting( + "Manual Enabled", setter_name="set_manual_enabled", icon="mdi:hand-back-left" + ) def is_manual_enabled(self) -> bool: """True if manual controls are enabled.""" return bool(self.data["is_manual_enabled"]) @@ -97,13 +99,19 @@ def polarity(self) -> Polarity: return Polarity(self.data["polarity"]) @property - @setting("Position Limited", setter_name="set_position_limit", icon="mdi:arrow-collapse-horizontal") + @setting( + "Position Limited", + setter_name="set_position_limit", + icon="mdi:arrow-collapse-horizontal", + ) def is_position_limited(self) -> bool: """Position limit.""" return bool(self.data["is_position_limited"]) @property - @setting("Night Tip Light", setter_name="set_night_tip_light", icon="mdi:lightbulb-night") + @setting( + "Night Tip Light", setter_name="set_night_tip_light", icon="mdi:lightbulb-night" + ) def night_tip_light(self) -> bool: """Night tip light status.""" return bool(self.data["night_tip_light"]) diff --git a/miio/integrations/mijia/vacuum/g1vacuum.py b/miio/integrations/mijia/vacuum/g1vacuum.py index bfd6904a1..fba7873d9 100644 --- a/miio/integrations/mijia/vacuum/g1vacuum.py +++ b/miio/integrations/mijia/vacuum/g1vacuum.py @@ -158,26 +158,26 @@ def __init__(self, data): ] """ self.data = data - @property + @property @sensor("Battery", unit="%", device_class="battery", icon="mdi:battery") def battery(self) -> int: """Battery Level.""" return self.data["battery"] - @property + @property @sensor("Charge State", icon="mdi:battery-charging") def charge_state(self) -> G1ChargeState: """Charging State.""" return G1ChargeState(self.data["charge_state"]) - @property + @property @sensor("Error Code", icon="mdi:alert-circle") def error_code(self) -> int: """Error code as returned by the device.""" return int(self.data["error_code"]) - @property + @property @sensor("Error", icon="mdi:alert-circle") def error(self) -> str: """Human readable error description, see also :func:`error_code`.""" @@ -188,78 +188,81 @@ def error(self) -> str: @property + @property @sensor("State", icon="mdi:robot-vacuum") def state(self) -> G1State: """Vacuum Status.""" return G1State(self.data["state"]) - @property - @setting("Fan Speed", setter_name="set_fan_speed", choices=G1FanSpeed, icon="mdi:fan") + @property + @setting( + "Fan Speed", setter_name="set_fan_speed", choices=G1FanSpeed, icon="mdi:fan" + ) def fan_speed(self) -> G1FanSpeed: """Fan Speed.""" return G1FanSpeed(self.data["fan_speed"]) - @property + @property @sensor("Operating Mode", icon="mdi:robot-vacuum") def operating_mode(self) -> G1VacuumMode: """Operating Mode.""" return G1VacuumMode(self.data["operating_mode"]) - @property + @property @sensor("Mop State", icon="mdi:robot-vacuum-variant") def mop_state(self) -> G1MopState: """Mop State.""" return G1MopState(self.data["mop_state"]) - @property + @property @sensor("Water Level", icon="mdi:water") def water_level(self) -> G1WaterLevel: """Water Level.""" return G1WaterLevel(self.data["water_level"]) - @property + @property @sensor("Main Brush Life Level", unit="%", icon="mdi:brush") def main_brush_life_level(self) -> int: """Main Brush Life Level in %.""" return self.data["main_brush_life_level"] - @property + @property @sensor("Main Brush Time Left", icon="mdi:brush") def main_brush_time_left(self) -> timedelta: """Main Brush Remaining Time in Minutes.""" return timedelta(minutes=self.data["main_brush_time_left"]) - @property + @property @sensor("Side Brush Life Level", unit="%", icon="mdi:brush") def side_brush_life_level(self) -> int: """Side Brush Life Level in %.""" return self.data["side_brush_life_level"] - @property + @property @sensor("Side Brush Time Left", icon="mdi:brush") def side_brush_time_left(self) -> timedelta: """Side Brush Remaining Time in Minutes.""" return timedelta(minutes=self.data["side_brush_time_left"]) - @property + @property @sensor("Filter Life Level", unit="%", icon="mdi:filter-outline") def filter_life_level(self) -> int: """Filter Life Level in %.""" return self.data["filter_life_level"] - @property + @property @sensor("Filter Time Left", icon="mdi:filter-outline") def filter_time_left(self) -> timedelta: """Filter remaining time.""" return timedelta(minutes=self.data["filter_time_left"]) - @property + @property @sensor("Clean Area", unit="cm²", icon="mdi:texture-box") def clean_area(self) -> int: """Clean Area in cm2.""" return self.data["clean_area"] - @property + @property @sensor("Clean Time", icon="mdi:timer-outline") def clean_time(self) -> timedelta: """Clean time.""" @@ -280,20 +283,20 @@ class G1CleaningSummary(DeviceStatus): def __init__(self, data) -> None: self.data = data - @property + @property @sensor("Total Clean Count", icon="mdi:counter") def total_clean_count(self) -> int: """Total Number of Cleanings.""" return self.data["total_clean_count"] - @property + @property @sensor("Total Clean Area", unit="m²", icon="mdi:texture-box") def total_clean_area(self) -> int: """Total Area Cleaned in m2.""" return self.data["total_clean_area"] - @property + @property @sensor("Total Clean Time", icon="mdi:timer-outline") def total_clean_time(self) -> timedelta: """Total Cleaning Time.""" diff --git a/miio/integrations/nwt/dehumidifier/airdehumidifier.py b/miio/integrations/nwt/dehumidifier/airdehumidifier.py index 9a3b33b36..6bb1c5b68 100644 --- a/miio/integrations/nwt/dehumidifier/airdehumidifier.py +++ b/miio/integrations/nwt/dehumidifier/airdehumidifier.py @@ -90,6 +90,7 @@ def mode(self) -> OperationMode: return OperationMode(self.data["mode"]) @property + @sensor( @sensor("Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") def temperature(self) -> float | None: """Current temperature, if available.""" diff --git a/miio/integrations/philips/light/philips_bulb.py b/miio/integrations/philips/light/philips_bulb.py index afd729093..a548323a7 100644 --- a/miio/integrations/philips/light/philips_bulb.py +++ b/miio/integrations/philips/light/philips_bulb.py @@ -48,6 +48,7 @@ def is_on(self) -> bool: return self.power == "on" @property + @setting( @setting("Brightness", setter_name="set_brightness", unit="%", icon="mdi:brightness-6") def brightness(self) -> int | None: if "bright" in self.data: @@ -57,6 +58,7 @@ def brightness(self) -> int | None: return None @property + @setting( @setting("Color Temperature", setter_name="set_color_temperature", icon="mdi:palette") def color_temperature(self) -> int | None: if "cct" in self.data: @@ -71,7 +73,12 @@ def scene(self) -> int | None: return None @property - @sensor("Delay Off Countdown", unit="s", icon="mdi:timer-outline", device_class="duration") + @sensor( + "Delay Off Countdown", + unit="s", + icon="mdi:timer-outline", + device_class="duration", + ) def delay_off_countdown(self) -> int: return self.data["dv"] diff --git a/miio/integrations/philips/light/philips_eyecare.py b/miio/integrations/philips/light/philips_eyecare.py index 9ab0f40ca..68fb1a226 100644 --- a/miio/integrations/philips/light/philips_eyecare.py +++ b/miio/integrations/philips/light/philips_eyecare.py @@ -89,13 +89,22 @@ def scene(self) -> int: return self.data["scene_num"] @property - @setting("Smart Night Light", setter_name="smart_night_light_on", icon="mdi:weather-night") + @setting( + "Smart Night Light", + setter_name="smart_night_light_on", + icon="mdi:weather-night", + ) def smart_night_light(self) -> bool: """True if the smart night light mode is on.""" return self.data["bls"] == "on" @property - @sensor("Delay Off Countdown", unit="min", icon="mdi:timer-sand", device_class="duration") + @sensor( + "Delay Off Countdown", + unit="min", + icon="mdi:timer-sand", + device_class="duration", + ) def delay_off_countdown(self) -> int: """Countdown until turning off in minutes.""" return self.data["dvalue"] diff --git a/miio/integrations/philips/light/philips_rwread.py b/miio/integrations/philips/light/philips_rwread.py index ee209d222..ade2f17b5 100644 --- a/miio/integrations/philips/light/philips_rwread.py +++ b/miio/integrations/philips/light/philips_rwread.py @@ -87,7 +87,9 @@ def scene(self) -> int: return self.data["snm"] @property - @setting("Motion Detection", setter_name="set_motion_detection", icon="mdi:motion-sensor") + @setting( + "Motion Detection", setter_name="set_motion_detection", icon="mdi:motion-sensor" + ) def motion_detection(self) -> bool: """True if motion detection is enabled.""" return self.data["flm"] == 1 diff --git a/miio/integrations/roidmi/vacuum/roidmivacuum_miot.py b/miio/integrations/roidmi/vacuum/roidmivacuum_miot.py index 5a546c955..66ea404a9 100644 --- a/miio/integrations/roidmi/vacuum/roidmivacuum_miot.py +++ b/miio/integrations/roidmi/vacuum/roidmivacuum_miot.py @@ -223,20 +223,20 @@ def __init__(self, data): ] """ self.data = data - @property + @property @sensor("Battery", unit="%", device_class="battery", icon="mdi:battery") def battery(self) -> int: """Remaining battery in percentage.""" return self.data["battery_level"] - @property + @property @sensor("Error Code", icon="mdi:alert-circle") def error_code(self) -> int: """Error code as returned by the device.""" return int(self.data["error_code"]) - @property + @property @sensor("Error", icon="mdi:alert-circle") def error(self) -> str: """Human readable error description, see also :func:`error_code`.""" @@ -247,6 +247,7 @@ def error(self) -> str: @property + @property @sensor("Charging State", icon="mdi:battery-charging") def charging_state(self) -> ChargingState: """Charging state (Charging/Discharging)""" @@ -255,8 +256,8 @@ def charging_state(self) -> ChargingState: except ValueError: _LOGGER.error("Unknown ChargingStats (%s)", self.data["charging_state"]) return ChargingState.Unknown - @property + @property @sensor("Sweep Mode", icon="mdi:robot-vacuum") def sweep_mode(self) -> SweepMode: """Sweep mode point/area/total etc.""" @@ -265,8 +266,8 @@ def sweep_mode(self) -> SweepMode: except ValueError: _LOGGER.error("Unknown SweepMode (%s)", self.data["sweep_mode"]) return SweepMode.Unknown - @property + @property @setting("Fan Speed", setter_name="set_fanspeed", choices=FanSpeed, icon="mdi:fan") def fan_speed(self) -> FanSpeed: """Current fan speed.""" @@ -275,9 +276,14 @@ def fan_speed(self) -> FanSpeed: except ValueError: _LOGGER.error("Unknown FanSpeed (%s)", self.data["fanspeed_mode"]) return FanSpeed.Unknown - @property - @setting("Sweep Type", setter_name="set_sweep_type", choices=SweepType, icon="mdi:robot-vacuum") + @property + @setting( + "Sweep Type", + setter_name="set_sweep_type", + choices=SweepType, + icon="mdi:robot-vacuum", + ) def sweep_type(self) -> SweepType: """Current sweep type sweep/mop/sweep&mop.""" try: @@ -285,9 +291,14 @@ def sweep_type(self) -> SweepType: except ValueError: _LOGGER.error("Unknown SweepType (%s)", self.data["sweep_type"]) return SweepType.Unknown - @property - @setting("Path Mode", setter_name="set_path_mode", choices=PathMode, icon="mdi:map-marker-path") + @property + @setting( + "Path Mode", + setter_name="set_path_mode", + choices=PathMode, + icon="mdi:map-marker-path", + ) def path_mode(self) -> PathMode: """Current path-mode: normal/y-mopping etc.""" try: @@ -295,23 +306,30 @@ def path_mode(self) -> PathMode: except ValueError: _LOGGER.error("Unknown PathMode (%s)", self.data["path_mode"]) return PathMode.Unknown - @property + @property @sensor("Mop Attached", icon="mdi:robot-vacuum-variant") def is_mop_attached(self) -> bool: """Return True if mop is attached.""" return self.data["mop_present"] - @property - @setting("Dust Collection Frequency", setter_name="set_dust_collection_frequency", min_value=0, max_value=3, step=1, icon="mdi:delete-variant") + @property + @setting( + "Dust Collection Frequency", + setter_name="set_dust_collection_frequency", + min_value=0, + max_value=3, + step=1, + icon="mdi:delete-variant", + ) def dust_collection_frequency(self) -> int: """Frequency for emptying the dust bin. Example: 2 means the dust bin is emptied every second cleaning. """ return self.data["work_station_freq"] - @property + @property @setting("Timing", setter_name="set_timing", icon="mdi:clock-outline") def timing(self) -> str: """Repeated cleaning. @@ -348,8 +366,8 @@ def timing(self) -> str: tz/tzs= time-zone """ return self.data["timing"] - @property + @property @setting("Carpet Mode", setter_name="set_carpet_mode", icon="mdi:rug") def carpet_mode(self) -> bool: """Auto boost on carpet.""" @@ -375,15 +393,20 @@ def _seconds_to_components(val): end_minute=end[1], ) ) - @property + @property @sensor("DND Status", icon="mdi:minus-circle") def dnd_status(self) -> DNDStatus: """Returns do-not-disturb status.""" return self._parse_forbid_mode(self.data["forbid_mode"]) - @property - @setting("Water Level", setter_name="set_water_level", choices=WaterLevel, icon="mdi:water") + @property + @setting( + "Water Level", + setter_name="set_water_level", + choices=WaterLevel, + icon="mdi:water", + ) def water_level(self) -> WaterLevel: """Get current water level.""" try: @@ -391,39 +414,43 @@ def water_level(self) -> WaterLevel: except ValueError: _LOGGER.error("Unknown WaterLevel (%s)", self.data["water_level"]) return WaterLevel.Unknown - @property + @property @setting("Double Clean", setter_name="set_double_clean", icon="mdi:refresh") def double_clean(self) -> bool: """Is double clean enabled.""" return self.data["double_clean"] - @property + @property @setting("LED", setter_name="set_led", icon="mdi:led-on") def led(self) -> bool: """Return True if led/display on vaccum is on.""" return self.data["led_switch"] - @property - @setting("Lidar Collision Sensor", setter_name="set_lidar_collision_sensor", icon="mdi:radar") + @property + @setting( + "Lidar Collision Sensor", + setter_name="set_lidar_collision_sensor", + icon="mdi:radar", + ) def is_lidar_collision_sensor(self) -> bool: """When ON, the robot will use lidar as the main detection sensor to help reduce collisions.""" return self.data["lidar_collision"] - @property + @property @sensor("Station Key", icon="mdi:gesture-tap-button") def station_key(self) -> bool: """When ON: long press the display will turn on dust collection.""" return self.data["station_key"] - @property + @property @setting("Station LED", setter_name="set_station_led", icon="mdi:led-on") def station_led(self) -> bool: """Return if station display is on.""" return self.data["station_led"] - @property + @property @sensor("Current Audio", icon="mdi:account-voice") def current_audio(self) -> str: """Current voice setting. @@ -431,26 +458,26 @@ def current_audio(self) -> str: E.g. 'girl_en' """ return self.data["current_audio"] - @property + @property @sensor("Clean Time", icon="mdi:timer-outline") def clean_time(self) -> timedelta: """Time used for cleaning (if finished, shows how long it took).""" return timedelta(seconds=self.data["clean_time_sec"]) - @property + @property @sensor("Clean Area", unit="m²", icon="mdi:texture-box") def clean_area(self) -> int: """Cleaned area in m2.""" return self.data["clean_area"] - @property + @property @sensor("State Code", icon="mdi:robot-vacuum") def state_code(self) -> int: """State code as returned by the device.""" return int(self.data["state"]) - @property + @property @sensor("State", icon="mdi:robot-vacuum") def state(self) -> RoidmiState: """Human readable state description, see also :func:`state_code`.""" @@ -459,32 +486,40 @@ def state(self) -> RoidmiState: except ValueError: _LOGGER.error("Unknown RoidmiState (%s)", self.state_code) return RoidmiState.Unknown - @property - @setting("Volume", setter_name="set_sound_volume", unit="%", min_value=0, max_value=100, step=1, icon="mdi:volume-high") + @property + @setting( + "Volume", + setter_name="set_sound_volume", + unit="%", + min_value=0, + max_value=100, + step=1, + icon="mdi:volume-high", + ) def volume(self) -> int: """Return device sound volumen level.""" return self.data["volume"] - @property + @property @setting("Muted", setter_name="set_sound_muted", icon="mdi:volume-off") def is_muted(self) -> bool: """True if device is muted.""" return bool(self.data["mute"]) - @property + @property @sensor("Is Paused", icon="mdi:pause-circle") def is_paused(self) -> bool: """Return True if vacuum is paused.""" return self.state in [RoidmiState.Paused, RoidmiState.FindChargerPause] - @property + @property @sensor("Is On", icon="mdi:robot-vacuum") def is_on(self) -> bool: """True if device is currently cleaning in any mode.""" return self.state == RoidmiState.Sweeping - @property + @property @sensor("Got Error", icon="mdi:alert-circle") def got_error(self) -> bool: """True if an error has occurred.""" @@ -496,20 +531,20 @@ class RoidmiCleaningSummary(DeviceStatus): def __init__(self, data) -> None: self.data = data - @property + @property @sensor("Total Duration", icon="mdi:timer-outline") def total_duration(self) -> timedelta: """Total cleaning duration.""" return timedelta(seconds=self.data["total_clean_time_sec"]) - @property + @property @sensor("Total Area", unit="m²", icon="mdi:texture-box") def total_area(self) -> int: """Total cleaned area.""" return self.data["total_clean_areas"] - @property + @property @sensor("Count", icon="mdi:counter") def count(self) -> int: """Number of cleaning runs.""" @@ -532,56 +567,56 @@ def _calcUsageTime( remaning_fraction = remaning_level / 100.0 original_total = renaning_time / remaning_fraction return original_total * (1 - remaning_fraction) - @property + @property @sensor("Filter Usage", icon="mdi:filter-outline") def filter(self) -> timedelta: """Filter usage time.""" return self._calcUsageTime(self.filter_left, self.data["filter_life_level"]) - @property + @property @sensor("Filter Left", icon="mdi:filter-outline") def filter_left(self) -> timedelta: """How long until the filter should be changed.""" return timedelta(minutes=self.data["filter_left_minutes"]) - @property + @property @sensor("Main Brush Usage", icon="mdi:brush") def main_brush(self) -> timedelta: """Main brush usage time.""" return self._calcUsageTime( self.main_brush_left, self.data["main_brush_life_level"] ) - @property + @property @sensor("Main Brush Left", icon="mdi:brush") def main_brush_left(self) -> timedelta: """How long until the main brush should be changed.""" return timedelta(minutes=self.data["main_brush_left_minutes"]) - @property + @property @sensor("Side Brush Usage", icon="mdi:brush") def side_brush(self) -> timedelta: """Main brush usage time.""" return self._calcUsageTime( self.side_brush_left, self.data["side_brushes_life_level"] ) - @property + @property @sensor("Side Brush Left", icon="mdi:brush") def side_brush_left(self) -> timedelta: """How long until the side brushes should be changed.""" return timedelta(minutes=self.data["side_brushes_left_minutes"]) - @property + @property @sensor("Sensor Dirty", icon="mdi:eye-off") def sensor_dirty(self) -> timedelta: """Return time since last sensor clean.""" return self._calcUsageTime( self.sensor_dirty_left, self.data["sensor_dirty_remaning_level"] ) - @property + @property @sensor("Sensor Dirty Left", icon="mdi:eye-off") def sensor_dirty_left(self) -> timedelta: """How long until the sensors should be cleaned.""" diff --git a/miio/integrations/tinymu/toiletlid/toiletlid.py b/miio/integrations/tinymu/toiletlid/toiletlid.py index ad112210a..45cb54e56 100644 --- a/miio/integrations/tinymu/toiletlid/toiletlid.py +++ b/miio/integrations/tinymu/toiletlid/toiletlid.py @@ -65,13 +65,23 @@ def filter_use_percentage(self) -> str: return "{}%".format(self.data["filter_use_flux"]) @property - @sensor("Filter Remaining Time", unit="d", icon="mdi:filter-outline", device_class="duration") + @sensor( + "Filter Remaining Time", + unit="d", + icon="mdi:filter-outline", + device_class="duration", + ) def filter_remaining_time(self) -> int: """Filter remaining life days.""" return self.data["filter_use_time"] @property - @setting("Ambient Light", setter_name="set_ambient_light", icon="mdi:lightbulb-variant", choices=AmbientLightColor) + @setting( + "Ambient Light", + setter_name="set_ambient_light", + icon="mdi:lightbulb-variant", + choices=AmbientLightColor, + ) def ambient_light(self) -> str: """Ambient light color.""" return self.data["ambient_light"] diff --git a/miio/integrations/xiaomi/aircondition/airconditioner_miot.py b/miio/integrations/xiaomi/aircondition/airconditioner_miot.py index 20347a34e..84106081c 100644 --- a/miio/integrations/xiaomi/aircondition/airconditioner_miot.py +++ b/miio/integrations/xiaomi/aircondition/airconditioner_miot.py @@ -79,26 +79,26 @@ def __init__(self, status: str): Only write 1 or 0 to it would start or abort the auto clean mode. """ self.status = [int(value) for value in status.split(",")] - @property + @property @sensor("Cleaning", icon="mdi:broom") def cleaning(self) -> bool: return bool(self.status[0]) - @property + @property @sensor("Progress", unit="%", icon="mdi:progress-check") def progress(self) -> int: return int(self.status[1]) - @property + @property @sensor("Stage", icon="mdi:broom") def stage(self) -> str: try: return CLEANING_STAGES[self.status[2]] except KeyError: return "Unknown stage" - @property + @property @sensor("Cancellable", icon="mdi:cancel") def cancellable(self) -> bool: return bool(self.status[3]) @@ -143,23 +143,23 @@ def __init__(self, status): Also, if the countdown minutes set to 0, the timer would be disabled. """ self.status = [int(value) for value in status.split(",")] - @property + @property @sensor("Enabled", icon="mdi:timer") def enabled(self) -> bool: return bool(self.status[0]) - @property + @property @sensor("Countdown", icon="mdi:timer-outline") def countdown(self) -> timedelta: return timedelta(minutes=self.status[1]) - @property + @property @sensor("Power On", icon="mdi:power") def power_on(self) -> bool: return bool(self.status[2]) - @property + @property @sensor("Time Left", icon="mdi:timer-outline") def time_left(self) -> timedelta: return timedelta(minutes=self.status[3]) @@ -193,110 +193,136 @@ def __init__(self, data: dict[str, Any]) -> None: """ self.data = data - @property + @property @sensor("Is On", icon="mdi:power") def is_on(self) -> bool: """True if the device is turned on.""" return self.data["power"] - @property + @property @sensor("Power", icon="mdi:power") def power(self) -> str: """Current power state.""" return "on" if self.is_on else "off" - @property - @setting("Mode", setter_name="set_mode", choices=OperationMode, icon="mdi:air-conditioner") + @property + @setting( + "Mode", + setter_name="set_mode", + choices=OperationMode, + icon="mdi:air-conditioner", + ) def mode(self) -> OperationMode: """Current operation mode.""" return OperationMode(self.data["mode"]) - @property - @setting("Target Temperature", setter_name="set_target_temperature", unit="°C", min_value=16, max_value=31, step=1, device_class="temperature", icon="mdi:thermometer") + @property + @setting( + "Target Temperature", + setter_name="set_target_temperature", + unit="°C", + min_value=16, + max_value=31, + step=1, + device_class="temperature", + icon="mdi:thermometer", + ) def target_temperature(self) -> float: """Target temperature in Celsius.""" return self.data["target_temperature"] - @property + @property @setting("ECO", setter_name="set_eco", icon="mdi:leaf") def eco(self) -> bool: """True if ECO mode is on.""" return self.data["eco"] - @property + @property @setting("Heater", setter_name="set_heater", icon="mdi:radiator") def heater(self) -> bool: """True if aux heat mode is on.""" return self.data["heater"] - @property + @property @setting("Dryer", setter_name="set_dryer", icon="mdi:water-off") def dryer(self) -> bool: """True if aux dryer mode is on.""" return self.data["dryer"] - @property + @property @setting("Sleep Mode", setter_name="set_sleep_mode", icon="mdi:sleep") def sleep_mode(self) -> bool: """True if sleep mode is on.""" return self.data["sleep_mode"] - @property + @property @setting("Fan Speed", setter_name="set_fan_speed", choices=FanSpeed, icon="mdi:fan") def fan_speed(self) -> FanSpeed: """Current Fan speed.""" return FanSpeed(self.data["fan_speed"]) - @property - @setting("Vertical Swing", setter_name="set_vertical_swing", icon="mdi:arrow-up-down") + @property + @setting( + "Vertical Swing", setter_name="set_vertical_swing", icon="mdi:arrow-up-down" + ) def vertical_swing(self) -> bool: """True if vertical swing is on.""" return self.data["vertical_swing"] - @property - @sensor("Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") + @property + @sensor( + "Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer" + ) def temperature(self) -> float: """Current ambient temperature in Celsius.""" return self.data["temperature"] - @property + @property @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") def buzzer(self) -> bool: """True if buzzer is on.""" return self.data["buzzer"] - @property + @property @setting("LED", setter_name="set_led", icon="mdi:led-on") def led(self) -> bool: """True if LED is on.""" return self.data["led"] - @property + @property @sensor("Electricity", unit="kWh", device_class="energy", icon="mdi:flash") def electricity(self) -> float: """Power consumption accumulation in kWh.""" return self.data["electricity"] - @property + @property @sensor("Clean", icon="mdi:broom") def clean(self) -> CleaningStatus: """Auto clean mode indicator.""" return CleaningStatus(self.data["clean"]) - @property + @property @sensor("Total Running Duration", icon="mdi:timer-outline") def total_running_duration(self) -> timedelta: """Total running duration in hours.""" return timedelta(hours=self.data["running_duration"]) - @property - @setting("Fan Speed Percent", setter_name="set_fan_speed_percent", unit="%", min_value=1, max_value=101, step=1, icon="mdi:fan") + @property + @setting( + "Fan Speed Percent", + setter_name="set_fan_speed_percent", + unit="%", + min_value=1, + max_value=101, + step=1, + icon="mdi:fan", + ) def fan_speed_percent(self) -> int: """Current fan speed in percent.""" return self.data["fan_speed_percent"] - @property + @property @sensor("Timer", icon="mdi:timer") def timer(self) -> TimerStatus: """Countdown timer indicator.""" diff --git a/miio/integrations/yeelight/dual_switch/yeelight_dual_switch.py b/miio/integrations/yeelight/dual_switch/yeelight_dual_switch.py index 961a6859b..2dda932a4 100644 --- a/miio/integrations/yeelight/dual_switch/yeelight_dual_switch.py +++ b/miio/integrations/yeelight/dual_switch/yeelight_dual_switch.py @@ -68,7 +68,11 @@ def switch_1_state(self) -> bool: return bool(self.data["switch_1_state"]) @property - @setting("Switch 1 Default State", setter_name="set_default_state", icon="mdi:toggle-switch-outline") + @setting( + "Switch 1 Default State", + setter_name="set_default_state", + icon="mdi:toggle-switch-outline", + ) def switch_1_default_state(self) -> bool: """First switch default state.""" return bool(self.data["switch_1_default_state"]) @@ -95,7 +99,11 @@ def switch_2_state(self) -> bool: return bool(self.data["switch_2_state"]) @property - @setting("Switch 2 Default State", setter_name="set_default_state", icon="mdi:toggle-switch-outline") + @setting( + "Switch 2 Default State", + setter_name="set_default_state", + icon="mdi:toggle-switch-outline", + ) def switch_2_default_state(self) -> bool: """Second switch default state.""" return bool(self.data["switch_2_default_state"]) diff --git a/miio/integrations/yunmi/waterpurifier/waterpurifier.py b/miio/integrations/yunmi/waterpurifier/waterpurifier.py index 599b45130..c6707a7b6 100644 --- a/miio/integrations/yunmi/waterpurifier/waterpurifier.py +++ b/miio/integrations/yunmi/waterpurifier/waterpurifier.py @@ -88,7 +88,9 @@ def usage(self) -> str: return self.data["usage"] @property - @sensor("Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") + @sensor( + "Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer" + ) def temperature(self) -> str: return self.data["temperature"] diff --git a/miio/integrations/yunmi/waterpurifier/waterpurifier_yunmi.py b/miio/integrations/yunmi/waterpurifier/waterpurifier_yunmi.py index be23cf308..a6b2ec8a4 100644 --- a/miio/integrations/yunmi/waterpurifier/waterpurifier_yunmi.py +++ b/miio/integrations/yunmi/waterpurifier/waterpurifier_yunmi.py @@ -94,8 +94,8 @@ def __init__(self, operation_status: int): for i in range(0, len(ERROR_DESCRIPTION)) if (1 << i) & operation_status ] - @property + @property @sensor("Errors", icon="mdi:alert-circle") def errors(self) -> list: return self.err_list @@ -119,146 +119,148 @@ def __init__(self, data: dict[str, Any]) -> None: 'filter3_flow_used': 1440, 'filter3_life_used': 3313} """ self.data = data - @property + @property @sensor("Operation Status", icon="mdi:information-outline") def operation_status(self) -> OperationStatus: """Current operation status.""" return OperationStatus(self.data["run_status"]) - @property + @property @sensor("Filter 1 Life Total", icon="mdi:filter-outline") def filter1_life_total(self) -> timedelta: """Filter1 total available time in hours.""" return timedelta(hours=self.data["f1_totaltime"]) - @property + @property @sensor("Filter 1 Life Used", icon="mdi:filter-outline") def filter1_life_used(self) -> timedelta: """Filter1 used time in hours.""" return timedelta(hours=self.data["f1_usedtime"]) - @property + @property @sensor("Filter 1 Life Remaining", icon="mdi:filter-outline") def filter1_life_remaining(self) -> timedelta: """Filter1 remaining time in hours.""" return self.filter1_life_total - self.filter1_life_used - @property + @property @sensor("Filter 1 Flow Total", unit="L", icon="mdi:water") def filter1_flow_total(self) -> int: """Filter1 total available flow in Metric Liter (L).""" return self.data["f1_totalflow"] - @property + @property @sensor("Filter 1 Flow Used", unit="L", icon="mdi:water") def filter1_flow_used(self) -> int: """Filter1 used flow in Metric Liter (L).""" return self.data["f1_usedflow"] - @property + @property @sensor("Filter 1 Flow Remaining", unit="L", icon="mdi:water") def filter1_flow_remaining(self) -> int: """Filter1 remaining flow in Metric Liter (L).""" return self.filter1_flow_total - self.filter1_flow_used - @property + @property @sensor("Filter 2 Life Total", icon="mdi:filter-outline") def filter2_life_total(self) -> timedelta: """Filter2 total available time in hours.""" return timedelta(hours=self.data["f2_totaltime"]) - @property + @property @sensor("Filter 2 Life Used", icon="mdi:filter-outline") def filter2_life_used(self) -> timedelta: """Filter2 used time in hours.""" return timedelta(hours=self.data["f2_usedtime"]) - @property + @property @sensor("Filter 2 Life Remaining", icon="mdi:filter-outline") def filter2_life_remaining(self) -> timedelta: """Filter2 remaining time in hours.""" return self.filter2_life_total - self.filter2_life_used - @property + @property @sensor("Filter 2 Flow Total", unit="L", icon="mdi:water") def filter2_flow_total(self) -> int: """Filter2 total available flow in Metric Liter (L).""" return self.data["f2_totalflow"] - @property + @property @sensor("Filter 2 Flow Used", unit="L", icon="mdi:water") def filter2_flow_used(self) -> int: """Filter2 used flow in Metric Liter (L).""" return self.data["f2_usedflow"] - @property + @property @sensor("Filter 2 Flow Remaining", unit="L", icon="mdi:water") def filter2_flow_remaining(self) -> int: """Filter2 remaining flow in Metric Liter (L).""" return self.filter2_flow_total - self.filter2_flow_used - @property + @property @sensor("Filter 3 Life Total", icon="mdi:filter-outline") def filter3_life_total(self) -> timedelta: """Filter3 total available time in hours.""" return timedelta(hours=self.data["f3_totaltime"]) - @property + @property @sensor("Filter 3 Life Used", icon="mdi:filter-outline") def filter3_life_used(self) -> timedelta: """Filter3 used time in hours.""" return timedelta(hours=self.data["f3_usedtime"]) - @property + @property @sensor("Filter 3 Life Remaining", icon="mdi:filter-outline") def filter3_life_remaining(self) -> timedelta: """Filter3 remaining time in hours.""" return self.filter3_life_total - self.filter3_life_used - @property + @property @sensor("Filter 3 Flow Total", unit="L", icon="mdi:water") def filter3_flow_total(self) -> int: """Filter3 total available flow in Metric Liter (L).""" return self.data["f3_totalflow"] - @property + @property @sensor("Filter 3 Flow Used", unit="L", icon="mdi:water") def filter3_flow_used(self) -> int: """Filter3 used flow in Metric Liter (L).""" return self.data["f3_usedflow"] - @property + @property @sensor("Filter 3 Flow Remaining", unit="L", icon="mdi:water") def filter3_flow_remaining(self) -> int: """Filter1 remaining flow in Metric Liter (L).""" return self.filter3_flow_total - self.filter3_flow_used - @property + @property @sensor("TDS In", unit="ppm", icon="mdi:water-check") def tds_in(self) -> int: """TDS value of input water.""" return self.data["tds_in"] - @property + @property @sensor("TDS Out", unit="ppm", icon="mdi:water-check") def tds_out(self) -> int: """TDS value of output water.""" return self.data["tds_out"] - @property + @property @sensor("Rinse", icon="mdi:water-sync") def rinse(self) -> bool: """True if the device is rinsing.""" return self.data["rinse"] - @property - @sensor("Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") + @property + @sensor( + "Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer" + ) def temperature(self) -> int: """Current water temperature in Celsius.""" return self.data["temperature"] - @property + @property @sensor("TDS Warning Threshold", unit="ppm", icon="mdi:water-alert") def tds_warn_thd(self) -> int: """TDS warning threshold.""" diff --git a/miio/integrations/zhimi/airpurifier/airfresh.py b/miio/integrations/zhimi/airpurifier/airfresh.py index 5e907a94f..7241c41f7 100644 --- a/miio/integrations/zhimi/airpurifier/airfresh.py +++ b/miio/integrations/zhimi/airpurifier/airfresh.py @@ -91,38 +91,38 @@ def __init__(self, data: dict[str, Any], model: str) -> None: self.data = data self.model = model - @property + @property @sensor("Power", icon="mdi:power") def power(self) -> str: """Power state.""" return self.data["power"] - @property + @property @sensor("Is On", icon="mdi:power") def is_on(self) -> bool: """Return True if device is on.""" return self.power == "on" - @property + @property @sensor("AQI", unit="μg/m³", icon="mdi:air-filter") def aqi(self) -> int: """Air quality index.""" return self.data["aqi"] - @property + @property @sensor("Average AQI", unit="μg/m³", icon="mdi:air-filter") def average_aqi(self) -> int: """Average of the air quality index.""" return self.data["average_aqi"] - @property + @property @sensor("CO2", unit="ppm", icon="mdi:molecule-co2", device_class="carbon_dioxide") def co2(self) -> int: """Carbon dioxide.""" return self.data["co2"] - @property + @property @sensor("Humidity", unit="%", device_class="humidity", icon="mdi:water-percent") def humidity(self) -> int: """Current humidity.""" @@ -135,6 +135,7 @@ def ptc(self) -> bool | None: return self.data["ptc_state"] == "on" return None + @sensor( @property @sensor("Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") def temperature(self) -> float | None: @@ -146,6 +147,7 @@ def temperature(self) -> float | None: return self.data["temp_dec"] / 10.0 return None + @sensor( @property @sensor("NTC Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") def ntc_temperature(self) -> float | None: @@ -154,18 +156,19 @@ def ntc_temperature(self) -> float | None: return self.data["ntcT"] return None - @property + @property @setting("Mode", setter_name="set_mode", choices=OperationMode, icon="mdi:fan") def mode(self) -> OperationMode: """Current operation mode.""" return OperationMode(self.data["mode"]) - @property + @property @setting("LED", setter_name="set_led", icon="mdi:led-on") def led(self) -> bool: """Return True if LED is on.""" return self.data["led"] == "on" + @setting( @property @setting("LED Brightness", setter_name="set_led_brightness", choices=LedBrightness, icon="mdi:brightness-6") def led_brightness(self) -> LedBrightness | None: @@ -188,32 +191,32 @@ def buzzer(self) -> bool | None: return self.data["buzzer"] == "on" return None - @property + @property @setting("Child Lock", setter_name="set_child_lock", icon="mdi:lock") def child_lock(self) -> bool: """Return True if child lock is on.""" return self.data["child_lock"] == "on" - @property + @property @sensor("Filter Life Remaining", unit="%", icon="mdi:filter-outline") def filter_life_remaining(self) -> int: """Time until the filter should be changed.""" return self.data["filter_life"] - @property + @property @sensor("Filter Hours Used", unit="h", icon="mdi:filter-outline") def filter_hours_used(self) -> int: """How long the filter has been in use.""" return self.data["f1_hour_used"] - @property + @property @sensor("Use Time", unit="s", icon="mdi:timer-sand") def use_time(self) -> int: """How long the device has been active in seconds.""" return self.data["use_time"] - @property + @property @sensor("Motor Speed", unit="rpm", icon="mdi:fan") def motor_speed(self) -> int: """Speed of the motor.""" diff --git a/miio/integrations/zhimi/airpurifier/airpurifier.py b/miio/integrations/zhimi/airpurifier/airpurifier.py index b9d20712d..5b33d3ada 100644 --- a/miio/integrations/zhimi/airpurifier/airpurifier.py +++ b/miio/integrations/zhimi/airpurifier/airpurifier.py @@ -129,36 +129,37 @@ def __init__(self, data: dict[str, Any]) -> None: self.filter_type_util = FilterTypeUtil() self.data = data - @property + @property @sensor("Power", icon="mdi:power") def power(self) -> str: """Power state.""" return self.data["power"] - @property + @property @sensor("Is On", icon="mdi:power") def is_on(self) -> bool: """Return True if device is on.""" return self.power == "on" - @property + @property @sensor("AQI", unit="μg/m³", icon="mdi:air-filter") def aqi(self) -> int: """Air quality index.""" return self.data["aqi"] - @property + @property @sensor("Average AQI", unit="μg/m³", icon="mdi:air-filter") def average_aqi(self) -> int: """Average of the air quality index.""" return self.data["average_aqi"] - @property + @property @sensor("Humidity", unit="%", device_class="humidity", icon="mdi:water-percent") def humidity(self) -> int: """Current humidity.""" return self.data["humidity"] + @sensor( @property @sensor("Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") def temperature(self) -> float | None: @@ -167,9 +168,11 @@ def temperature(self) -> float | None: return self.data["temp_dec"] / 10.0 return None - @property - @setting("Mode", setter_name="set_mode", choices=OperationMode, icon="mdi:air-purifier") + @property + @setting( + "Mode", setter_name="set_mode", choices=OperationMode, icon="mdi:air-purifier" + ) def mode(self) -> OperationMode: """Current operation mode.""" return OperationMode(self.data["mode"]) @@ -184,12 +187,13 @@ def sleep_mode(self) -> SleepMode | None: return SleepMode(self.data["sleep_mode"]) return None - @property + @property @setting("LED", setter_name="set_led", icon="mdi:led-on") def led(self) -> bool: """Return True if LED is on.""" return self.data["led"] == "on" + @setting( @property @setting("LED Brightness", setter_name="set_led_brightness", choices=LedBrightness, icon="mdi:brightness-6") def led_brightness(self) -> LedBrightness | None: @@ -201,6 +205,7 @@ def led_brightness(self) -> LedBrightness | None: return None return None + @sensor( @property @sensor("Illuminance", unit="lx", device_class="illuminance", icon="mdi:brightness-5") def illuminance(self) -> int | None: @@ -217,45 +222,52 @@ def buzzer(self) -> bool | None: return self.data["buzzer"] == "on" return None - @property + @property @setting("Child Lock", setter_name="set_child_lock", icon="mdi:lock") def child_lock(self) -> bool: """Return True if child lock is on.""" return self.data["child_lock"] == "on" - @property - @setting("Favorite Level", setter_name="set_favorite_level", min_value=0, max_value=17, step=1, icon="mdi:star") + @property + @setting( + "Favorite Level", + setter_name="set_favorite_level", + min_value=0, + max_value=17, + step=1, + icon="mdi:star", + ) def favorite_level(self) -> int: """Return favorite level, which is used if the mode is ``favorite``.""" # Favorite level used when the mode is `favorite`. return self.data["favorite_level"] - @property + @property @sensor("Filter Life Remaining", unit="%", icon="mdi:filter-outline") def filter_life_remaining(self) -> int: """Time until the filter should be changed.""" return self.data["filter1_life"] - @property + @property @sensor("Filter Hours Used", unit="h", icon="mdi:filter-outline") def filter_hours_used(self) -> int: """How long the filter has been in use.""" return self.data["f1_hour_used"] - @property + @property @sensor("Use Time", unit="s", icon="mdi:timer-sand") def use_time(self) -> int: """How long the device has been active in seconds.""" return self.data["use_time"] - @property + @property @sensor("Purify Volume", unit="m³", icon="mdi:air-purifier") def purify_volume(self) -> int: """The volume of purified air in cubic meter.""" return self.data["purify_volume"] - @property + @property @sensor("Motor Speed", unit="rpm", icon="mdi:fan") def motor_speed(self) -> int: """Speed of the motor.""" @@ -265,6 +277,7 @@ def motor_speed(self) -> int: def motor2_speed(self) -> int | None: """Speed of the 2nd motor.""" return self.data["motor2_speed"] + @setting( @property @setting("Volume", setter_name="set_volume", unit="%", min_value=0, max_value=100, step=1, icon="mdi:volume-high") def volume(self) -> int | None: @@ -287,8 +300,8 @@ def filter_type(self) -> FilterType | None: return self.filter_type_util.determine_filter_type( self.filter_rfid_tag, self.filter_rfid_product_id ) - @property + @property @setting("Learn Mode", setter_name="set_learn_mode", icon="mdi:school") def learn_mode(self) -> bool: """Return True if Learn Mode is enabled.""" diff --git a/miio/integrations/zhimi/fan/zhimi_miot.py b/miio/integrations/zhimi/fan/zhimi_miot.py index 62b29ae3a..3f9da5b70 100644 --- a/miio/integrations/zhimi/fan/zhimi_miot.py +++ b/miio/integrations/zhimi/fan/zhimi_miot.py @@ -81,20 +81,20 @@ def __init__(self, data: dict[str, Any]) -> None: {'code': 0, 'did': 'temperature', 'piid': 7, 'siid': 7, 'value': 26.4}, """ self.data = data - @property + @property @setting("Ionizer", setter_name="set_ionizer", icon="mdi:atom") def ionizer(self) -> bool: """True if negative ions generation is enabled.""" return self.data["anion"] - @property + @property @sensor("Battery Supported", icon="mdi:battery") def battery_supported(self) -> bool: """True if battery is supported.""" return self.data["battery_supported"] - @property + @property @sensor("Buttons Pressed", icon="mdi:gesture-tap-button") def buttons_pressed(self) -> str: """What buttons on the fan are pressed now.""" @@ -106,21 +106,28 @@ def buttons_pressed(self) -> str: if code == 2: return "Swing" return "Unknown" - @property + @property @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") def buzzer(self) -> bool: """True if buzzer is turned on.""" return self.data["buzzer"] - @property + @property @setting("Child Lock", setter_name="set_child_lock", icon="mdi:lock") def child_lock(self) -> bool: """True if child lock if on.""" return self.data["child_lock"] - @property - @setting("Fan Level", setter_name="set_fan_speed", min_value=1, max_value=4, step=1, icon="mdi:fan") + @property + @setting( + "Fan Level", + setter_name="set_fan_speed", + min_value=1, + max_value=4, + step=1, + icon="mdi:fan", + ) def fan_level(self) -> int: """Fan level (1-4).""" return self.data["fan_level"] @@ -130,75 +137,98 @@ def fan_level(self) -> int: def fan_speed(self) -> int: """Fan speed (1-100).""" return self.speed - @property - @setting("Speed", setter_name="set_speed", min_value=1, max_value=100, step=1, unit="%", icon="mdi:fan") + @property + @setting( + "Speed", + setter_name="set_speed", + min_value=1, + max_value=100, + step=1, + unit="%", + icon="mdi:fan", + ) def speed(self) -> int: """Fan speed (1-100).""" return self.data["fan_speed"] - @property + @property @sensor("Humidity", unit="%", device_class="humidity", icon="mdi:water-percent") def humidity(self) -> int: """Air humidity in percent.""" return self.data["humidity"] - @property - @setting("LED Brightness", setter_name="set_led_brightness", min_value=0, max_value=100, step=1, unit="%", icon="mdi:brightness-6") + @property + @setting( + "LED Brightness", + setter_name="set_led_brightness", + min_value=0, + max_value=100, + step=1, + unit="%", + icon="mdi:brightness-6", + ) def led_brightness(self) -> int: """LED brightness (1-100).""" return self.data["light"] - @property + @property @setting("Mode", setter_name="set_mode", choices=OperationMode, icon="mdi:fan") def mode(self) -> OperationMode: """Operation mode (normal or nature).""" return OperationMode[OperationModeFanZA5(self.data["mode"]).name] - @property + @property @sensor("Power", icon="mdi:power") def power(self) -> str: """Power state.""" return "on" if self.data["power"] else "off" - @property + @property @sensor("Is On", icon="mdi:power") def is_on(self) -> bool: """True if device is currently on.""" return self.data["power"] - @property - @setting("Delay Off Countdown", setter_name="delay_off", unit="s", icon="mdi:timer-off-outline") + @property + @setting( + "Delay Off Countdown", + setter_name="delay_off", + unit="s", + icon="mdi:timer-off-outline", + ) def delay_off_countdown(self) -> int: """Countdown until turning off in minutes.""" return self.data["power_off_time"] - @property + @property @sensor("Power Supply Attached", icon="mdi:power-plug") def powersupply_attached(self) -> bool: """True is power supply is attached.""" return self.data["powersupply_attached"] - @property + @property @sensor("Speed RPM", unit="rpm", icon="mdi:fan") def speed_rpm(self) -> int: """Fan rotations per minute.""" return self.data["speed_rpm"] - @property + @property @setting("Oscillate", setter_name="set_oscillate", icon="mdi:arrow-left-right") def oscillate(self) -> bool: """True if oscillation is enabled.""" return self.data["swing_mode"] - @property + @property @setting("Angle", setter_name="set_angle", icon="mdi:angle-acute") def angle(self) -> int: """Oscillation angle.""" return self.data["swing_mode_angle"] - @property - @sensor("Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") + @property + @sensor( + "Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer" + ) def temperature(self) -> Any: """Air temperature (degree celsius).""" return self.data["temperature"] diff --git a/miio/integrations/zhimi/heater/heater.py b/miio/integrations/zhimi/heater/heater.py index a77ef7c72..c1e4ac724 100644 --- a/miio/integrations/zhimi/heater/heater.py +++ b/miio/integrations/zhimi/heater/heater.py @@ -82,7 +82,9 @@ def humidity(self) -> int | None: return None @property - @sensor("Temperature", unit="°C", icon="mdi:thermometer", device_class="temperature") + @sensor( + "Temperature", unit="°C", icon="mdi:thermometer", device_class="temperature" + ) def temperature(self) -> float: """Current temperature.""" return self.data["temperature"] @@ -131,6 +133,7 @@ def use_time(self) -> int: return self.data["use_time"] @property + @sensor( @sensor("Delay Off Countdown", unit="s", icon="mdi:timer-sand", device_class="duration") def delay_off_countdown(self) -> int | None: """Countdown until turning off in seconds.""" diff --git a/miio/integrations/zhimi/heater/heater_miot.py b/miio/integrations/zhimi/heater/heater_miot.py index 0d76e6bdf..2fb48268c 100644 --- a/miio/integrations/zhimi/heater/heater_miot.py +++ b/miio/integrations/zhimi/heater/heater_miot.py @@ -148,18 +148,23 @@ def target_temperature(self) -> int: return self.data["target_temperature"] @property - @sensor("Delay Off Countdown", unit="s", icon="mdi:timer-sand", device_class="duration") + @sensor( + "Delay Off Countdown", unit="s", icon="mdi:timer-sand", device_class="duration" + ) def delay_off_countdown(self) -> int: """Countdown until turning off in seconds.""" return self.data["countdown_time"] @property - @sensor("Temperature", unit="°C", icon="mdi:thermometer", device_class="temperature") + @sensor( + "Temperature", unit="°C", icon="mdi:thermometer", device_class="temperature" + ) def temperature(self) -> float: """Current temperature.""" return self.data["temperature"] @property + @sensor( @sensor("Relative Humidity", unit="%", icon="mdi:water-percent", device_class="humidity") def relative_humidity(self) -> int | None: """Current relative humidity.""" From 09d1c7add945a3e9b8a90635b62d608cc9a3e6bc Mon Sep 17 00:00:00 2001 From: Teemu Rytilahti Date: Sun, 5 Jul 2026 15:29:37 +0200 Subject: [PATCH 3/7] Fix broken decorators left from rebase conflict resolution --- .../cgllc/airmonitor/airqualitymonitor.py | 5 +-- miio/integrations/chunmi/cooker/cooker.py | 10 ++++- .../deerma/humidifier/airhumidifier_jsqs.py | 6 ++- .../deerma/humidifier/airhumidifier_mjjsq.py | 3 +- .../dmaker/airfresh/airfresh_t2017.py | 4 +- .../dreame/vacuum/dreamevacuum_miot.py | 11 ++++- miio/integrations/huayi/light/huizuo.py | 2 - .../acpartner/airconditioningcompanion.py | 6 ++- .../acpartner/airconditioningcompanionMCN.py | 19 ++++++-- miio/integrations/mijia/vacuum/g1vacuum.py | 2 - .../nwt/dehumidifier/airdehumidifier.py | 5 +-- .../philips/light/philips_bulb.py | 6 ++- .../roidmi/vacuum/roidmivacuum_miot.py | 2 - .../zhimi/airpurifier/airfresh.py | 24 +++++++--- .../zhimi/airpurifier/airpurifier.py | 45 +++++++++++++++---- miio/integrations/zhimi/heater/heater.py | 3 +- miio/integrations/zhimi/heater/heater_miot.py | 3 +- 17 files changed, 114 insertions(+), 42 deletions(-) diff --git a/miio/integrations/cgllc/airmonitor/airqualitymonitor.py b/miio/integrations/cgllc/airmonitor/airqualitymonitor.py index c179bcf53..518cb3497 100644 --- a/miio/integrations/cgllc/airmonitor/airqualitymonitor.py +++ b/miio/integrations/cgllc/airmonitor/airqualitymonitor.py @@ -124,13 +124,11 @@ def sensor_state(self) -> str | None: return self.data.get("sensor_state") @property - @sensor( def co2(self) -> int | None: """Return co2 value (400...9999ppm).""" return self.data.get("co2") @property - @sensor( def co2e(self) -> int | None: """Return co2e value (400...9999ppm).""" return self.data.get("co2e") @@ -149,7 +147,8 @@ def pm25(self) -> float | None: @property @sensor( - @sensor("Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") + "Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer" + ) def temperature(self) -> float | None: """Return temperature value (-10...50°C).""" return self.data.get("temperature") diff --git a/miio/integrations/chunmi/cooker/cooker.py b/miio/integrations/chunmi/cooker/cooker.py index 305950cd0..b7462d9b3 100644 --- a/miio/integrations/chunmi/cooker/cooker.py +++ b/miio/integrations/chunmi/cooker/cooker.py @@ -508,6 +508,7 @@ def mode(self) -> OperationMode: def menu(self) -> int: """Selected recipe id.""" return int(self.data["menu"], 16) + @property @sensor("Stage", icon="mdi:pot-steam") def stage(self) -> CookingStage | None: @@ -517,9 +518,11 @@ def stage(self) -> CookingStage | None: return CookingStage(stage) return None - @sensor( + @property - @sensor("Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") + @sensor( + "Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer" + ) def temperature(self) -> int | None: """Current temperature, if idle. @@ -530,6 +533,7 @@ def temperature(self) -> int | None: return int(value) return None + @property @sensor("Start Time", icon="mdi:clock-start") def start_time(self) -> time | None: @@ -549,6 +553,7 @@ def start_time(self) -> time | None: def remaining(self) -> int: """Remaining minutes of the cooking process.""" return int(self.data["t_func"]) + @property @sensor("Cooking Delayed", unit="min", icon="mdi:timer-sand") def cooking_delayed(self) -> int | None: @@ -598,6 +603,7 @@ def favorite(self) -> int: Can be compared with the menu property. """ return int(self.data["favorite"], 16) + @property @sensor("Custom", icon="mdi:tune") def custom(self) -> CookerCustomizations | None: diff --git a/miio/integrations/deerma/humidifier/airhumidifier_jsqs.py b/miio/integrations/deerma/humidifier/airhumidifier_jsqs.py index e2d6095e5..1f3ce5c43 100644 --- a/miio/integrations/deerma/humidifier/airhumidifier_jsqs.py +++ b/miio/integrations/deerma/humidifier/airhumidifier_jsqs.py @@ -106,7 +106,6 @@ def mode(self) -> OperationMode: return mode @property - @setting( def target_humidity(self) -> int | None: """Return target humidity.""" return self.data.get("target_humidity") @@ -157,7 +156,10 @@ def water_shortage_fault(self) -> bool | None: @property @setting( - @setting(name="Overwet Protect", setter_name="set_overwet_protect", icon="mdi:shield-check") + name="Overwet Protect", + setter_name="set_overwet_protect", + icon="mdi:shield-check", + ) def overwet_protect(self) -> bool | None: """Return True if overwet mode is active.""" return self.data.get("overwet_protect") diff --git a/miio/integrations/deerma/humidifier/airhumidifier_mjjsq.py b/miio/integrations/deerma/humidifier/airhumidifier_mjjsq.py index d2bce51bd..10889824f 100644 --- a/miio/integrations/deerma/humidifier/airhumidifier_mjjsq.py +++ b/miio/integrations/deerma/humidifier/airhumidifier_mjjsq.py @@ -132,7 +132,8 @@ def water_tank_detached(self) -> bool: @property @setting( - @setting(name="Wet Protection", setter_name="set_wet_protection", icon="mdi:shield-check") + name="Wet Protection", setter_name="set_wet_protection", icon="mdi:shield-check" + ) def wet_protection(self) -> bool | None: """True if wet protection is enabled.""" if self.data["wet_and_protect"] is not None: diff --git a/miio/integrations/dmaker/airfresh/airfresh_t2017.py b/miio/integrations/dmaker/airfresh/airfresh_t2017.py index 2e843086f..ab2e66754 100644 --- a/miio/integrations/dmaker/airfresh/airfresh_t2017.py +++ b/miio/integrations/dmaker/airfresh/airfresh_t2017.py @@ -208,7 +208,8 @@ def ptc(self) -> bool: @property @setting( - @setting("PTC Level", setter_name="set_ptc_level", choices=PtcLevel, icon="mdi:radiator") + "PTC Level", setter_name="set_ptc_level", choices=PtcLevel, icon="mdi:radiator" + ) def ptc_level(self) -> PtcLevel | None: """PTC level.""" try: @@ -241,7 +242,6 @@ def display(self) -> bool: return self.data["display"] @property - @setting( def display_orientation(self) -> DisplayOrientation | None: """Display orientation.""" try: diff --git a/miio/integrations/dreame/vacuum/dreamevacuum_miot.py b/miio/integrations/dreame/vacuum/dreamevacuum_miot.py index e70eb4b7c..8c21bd46e 100644 --- a/miio/integrations/dreame/vacuum/dreamevacuum_miot.py +++ b/miio/integrations/dreame/vacuum/dreamevacuum_miot.py @@ -339,6 +339,7 @@ def filter_left_time(self) -> str: @sensor("Filter Life Level", unit="%", icon="mdi:filter-outline") def filter_life_level(self) -> str: return self.data["filter_life_level"] + @property @sensor("Device Fault", icon="mdi:alert-circle") def device_fault(self) -> FaultStatus | None: @@ -347,6 +348,7 @@ def device_fault(self) -> FaultStatus | None: except ValueError: _LOGGER.error("Unknown FaultStatus (%s)", self.data["device_fault"]) return None + @property @sensor("Charging State", icon="mdi:battery-charging") def charging_state(self) -> ChargingState | None: @@ -355,6 +357,7 @@ def charging_state(self) -> ChargingState | None: except ValueError: _LOGGER.error("Unknown ChargingStats (%s)", self.data["charging_state"]) return None + @property @sensor("Operating Mode", icon="mdi:robot-vacuum") def operating_mode(self) -> OperatingMode | None: @@ -363,6 +366,7 @@ def operating_mode(self) -> OperatingMode | None: except ValueError: _LOGGER.error("Unknown OperatingMode (%s)", self.data["operating_mode"]) return None + @property @sensor("Device Status", icon="mdi:robot-vacuum") def device_status(self) -> DeviceStatus | None: @@ -459,14 +463,17 @@ def cleaning_mode(self): except ValueError: _LOGGER.error(f"Unknown CleaningMode ({cleaning_mode})") return None + @property @sensor("Life Sieve", unit="%", icon="mdi:filter-outline") def life_sieve(self) -> str | None: return self.data.get("life_sieve") + @property @sensor("Life Brush Side", unit="%", icon="mdi:brush") def life_brush_side(self) -> str | None: return self.data.get("life_brush_side") + @property @sensor("Life Brush Main", unit="%", icon="mdi:brush") def life_brush_main(self) -> str | None: @@ -475,7 +482,8 @@ def life_brush_main(self) -> str | None: # TODO: get/set water flow for Dreame 1C @property @setting( - @setting("Water Flow", setter_name="set_waterflow", choices=WaterFlow, icon="mdi:water") + "Water Flow", setter_name="set_waterflow", choices=WaterFlow, icon="mdi:water" + ) def water_flow(self) -> WaterFlow | None: try: water_flow = self.data["water_flow"] @@ -486,6 +494,7 @@ def water_flow(self) -> WaterFlow | None: except ValueError: _LOGGER.error("Unknown WaterFlow (%s)", self.data["water_flow"]) return None + @property @sensor("Water Box Carriage Attached", icon="mdi:cup-water") def is_water_box_carriage_attached(self) -> bool | None: diff --git a/miio/integrations/huayi/light/huizuo.py b/miio/integrations/huayi/light/huizuo.py index 98a446ae5..f599ca32a 100644 --- a/miio/integrations/huayi/light/huizuo.py +++ b/miio/integrations/huayi/light/huizuo.py @@ -159,7 +159,6 @@ def is_fan_on(self) -> bool | None: return None @property - @setting( def fan_speed_level(self) -> int | None: """Return current Fan speed level.""" if "fan_level" in self.data: @@ -202,7 +201,6 @@ def heater_fault_code(self) -> int | None: return None @property - @setting( def heat_level(self) -> int | None: """Return Heater's heat level.""" if "heat_level" in self.data: diff --git a/miio/integrations/lumi/acpartner/airconditioningcompanion.py b/miio/integrations/lumi/acpartner/airconditioningcompanion.py index 8d49e748d..50cab2694 100644 --- a/miio/integrations/lumi/acpartner/airconditioningcompanion.py +++ b/miio/integrations/lumi/acpartner/airconditioningcompanion.py @@ -197,7 +197,11 @@ def is_on(self) -> bool: @property @sensor( - @sensor("Target Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") + "Target Temperature", + unit="°C", + device_class="temperature", + icon="mdi:thermometer", + ) def target_temperature(self) -> int | None: """Target temperature.""" try: diff --git a/miio/integrations/lumi/acpartner/airconditioningcompanionMCN.py b/miio/integrations/lumi/acpartner/airconditioningcompanionMCN.py index f3ade1a10..72c54268c 100644 --- a/miio/integrations/lumi/acpartner/airconditioningcompanionMCN.py +++ b/miio/integrations/lumi/acpartner/airconditioningcompanionMCN.py @@ -64,7 +64,11 @@ def is_on(self) -> bool: @property @setting( - @setting("Mode", setter_name="send_command", icon="mdi:air-conditioner", choices=OperationMode) + "Mode", + setter_name="send_command", + icon="mdi:air-conditioner", + choices=OperationMode, + ) def mode(self) -> OperationMode | None: """Current operation mode.""" try: @@ -75,7 +79,12 @@ def mode(self) -> OperationMode | None: @property @setting( - @setting("Target Temperature", setter_name="send_command", unit="°C", icon="mdi:thermometer", device_class="temperature") + "Target Temperature", + setter_name="send_command", + unit="°C", + icon="mdi:thermometer", + device_class="temperature", + ) def target_temperature(self) -> int | None: """Target temperature.""" try: @@ -95,7 +104,11 @@ def fan_speed(self) -> FanSpeed | None: @property @setting( - @setting("Swing Mode", setter_name="send_command", icon="mdi:arrow-oscillating", choices=SwingMode) + "Swing Mode", + setter_name="send_command", + icon="mdi:arrow-oscillating", + choices=SwingMode, + ) def swing_mode(self) -> SwingMode | None: """Current swing mode.""" try: diff --git a/miio/integrations/mijia/vacuum/g1vacuum.py b/miio/integrations/mijia/vacuum/g1vacuum.py index fba7873d9..a2088c683 100644 --- a/miio/integrations/mijia/vacuum/g1vacuum.py +++ b/miio/integrations/mijia/vacuum/g1vacuum.py @@ -186,8 +186,6 @@ def error(self) -> str: except KeyError: return f"Definition missing for error {self.error_code}" - @property - @property @sensor("State", icon="mdi:robot-vacuum") def state(self) -> G1State: diff --git a/miio/integrations/nwt/dehumidifier/airdehumidifier.py b/miio/integrations/nwt/dehumidifier/airdehumidifier.py index 6bb1c5b68..167d3b37a 100644 --- a/miio/integrations/nwt/dehumidifier/airdehumidifier.py +++ b/miio/integrations/nwt/dehumidifier/airdehumidifier.py @@ -91,7 +91,8 @@ def mode(self) -> OperationMode: @property @sensor( - @sensor("Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") + "Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer" + ) def temperature(self) -> float | None: """Current temperature, if available.""" if "temp" in self.data and self.data["temp"] is not None: @@ -123,7 +124,6 @@ def child_lock(self) -> bool: return self.data["child_lock"] == "on" @property - @setting( def target_humidity(self) -> int | None: """Target humiditiy. @@ -134,7 +134,6 @@ def target_humidity(self) -> int | None: return None @property - @setting( def fan_speed(self) -> FanSpeed | None: """Current fan speed.""" if "fan_speed" in self.data and self.data["fan_speed"] is not None: diff --git a/miio/integrations/philips/light/philips_bulb.py b/miio/integrations/philips/light/philips_bulb.py index a548323a7..18e707b8b 100644 --- a/miio/integrations/philips/light/philips_bulb.py +++ b/miio/integrations/philips/light/philips_bulb.py @@ -49,7 +49,8 @@ def is_on(self) -> bool: @property @setting( - @setting("Brightness", setter_name="set_brightness", unit="%", icon="mdi:brightness-6") + "Brightness", setter_name="set_brightness", unit="%", icon="mdi:brightness-6" + ) def brightness(self) -> int | None: if "bright" in self.data: return self.data["bright"] @@ -59,7 +60,8 @@ def brightness(self) -> int | None: @property @setting( - @setting("Color Temperature", setter_name="set_color_temperature", icon="mdi:palette") + "Color Temperature", setter_name="set_color_temperature", icon="mdi:palette" + ) def color_temperature(self) -> int | None: if "cct" in self.data: return self.data["cct"] diff --git a/miio/integrations/roidmi/vacuum/roidmivacuum_miot.py b/miio/integrations/roidmi/vacuum/roidmivacuum_miot.py index 66ea404a9..5312d84fb 100644 --- a/miio/integrations/roidmi/vacuum/roidmivacuum_miot.py +++ b/miio/integrations/roidmi/vacuum/roidmivacuum_miot.py @@ -245,8 +245,6 @@ def error(self) -> str: except KeyError: return f"Definition missing for error {self.error_code}" - @property - @property @sensor("Charging State", icon="mdi:battery-charging") def charging_state(self) -> ChargingState: diff --git a/miio/integrations/zhimi/airpurifier/airfresh.py b/miio/integrations/zhimi/airpurifier/airfresh.py index 7241c41f7..4324a9e7f 100644 --- a/miio/integrations/zhimi/airpurifier/airfresh.py +++ b/miio/integrations/zhimi/airpurifier/airfresh.py @@ -127,6 +127,7 @@ def co2(self) -> int: def humidity(self) -> int: """Current humidity.""" return self.data["humidity"] + @property @setting("PTC", setter_name="set_ptc", icon="mdi:radiator") def ptc(self) -> bool | None: @@ -135,9 +136,11 @@ def ptc(self) -> bool | None: return self.data["ptc_state"] == "on" return None - @sensor( + @property - @sensor("Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") + @sensor( + "Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer" + ) def temperature(self) -> float | None: """Current temperature, if available.""" if self.data["temp_dec"] is not None: @@ -147,9 +150,11 @@ def temperature(self) -> float | None: return self.data["temp_dec"] / 10.0 return None - @sensor( + @property - @sensor("NTC Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") + @sensor( + "NTC Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer" + ) def ntc_temperature(self) -> float | None: """Current ntc temperature, if available.""" if self.data["ntcT"] is not None: @@ -168,9 +173,14 @@ def mode(self) -> OperationMode: def led(self) -> bool: """Return True if LED is on.""" return self.data["led"] == "on" - @setting( + @property - @setting("LED Brightness", setter_name="set_led_brightness", choices=LedBrightness, icon="mdi:brightness-6") + @setting( + "LED Brightness", + setter_name="set_led_brightness", + choices=LedBrightness, + icon="mdi:brightness-6", + ) def led_brightness(self) -> LedBrightness | None: """Brightness of the LED.""" if self.data["led_level"] is not None: @@ -183,6 +193,7 @@ def led_brightness(self) -> LedBrightness | None: return None return None + @property @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") def buzzer(self) -> bool | None: @@ -221,6 +232,7 @@ def use_time(self) -> int: def motor_speed(self) -> int: """Speed of the motor.""" return self.data["motor1_speed"] + @property @setting("Extra Features", setter_name="set_extra_features", icon="mdi:star") def extra_features(self) -> int | None: diff --git a/miio/integrations/zhimi/airpurifier/airpurifier.py b/miio/integrations/zhimi/airpurifier/airpurifier.py index 5b33d3ada..6495a3a8c 100644 --- a/miio/integrations/zhimi/airpurifier/airpurifier.py +++ b/miio/integrations/zhimi/airpurifier/airpurifier.py @@ -159,9 +159,11 @@ def average_aqi(self) -> int: def humidity(self) -> int: """Current humidity.""" return self.data["humidity"] - @sensor( + @property - @sensor("Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer") + @sensor( + "Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer" + ) def temperature(self) -> float | None: """Current temperature, if available.""" if self.data["temp_dec"] is not None: @@ -176,6 +178,7 @@ def temperature(self) -> float | None: def mode(self) -> OperationMode: """Current operation mode.""" return OperationMode(self.data["mode"]) + @property @sensor("Sleep Mode", icon="mdi:sleep") def sleep_mode(self) -> SleepMode | None: @@ -193,9 +196,14 @@ def sleep_mode(self) -> SleepMode | None: def led(self) -> bool: """Return True if LED is on.""" return self.data["led"] == "on" - @setting( + @property - @setting("LED Brightness", setter_name="set_led_brightness", choices=LedBrightness, icon="mdi:brightness-6") + @setting( + "LED Brightness", + setter_name="set_led_brightness", + choices=LedBrightness, + icon="mdi:brightness-6", + ) def led_brightness(self) -> LedBrightness | None: """Brightness of the LED.""" if self.data["led_b"] is not None: @@ -205,15 +213,18 @@ def led_brightness(self) -> LedBrightness | None: return None return None - @sensor( + @property - @sensor("Illuminance", unit="lx", device_class="illuminance", icon="mdi:brightness-5") + @sensor( + "Illuminance", unit="lx", device_class="illuminance", icon="mdi:brightness-5" + ) def illuminance(self) -> int | None: """Environment illuminance level in lux [0-200]. Sensor value is updated only when device is turned on. """ return self.data["bright"] + @property @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") def buzzer(self) -> bool | None: @@ -272,27 +283,39 @@ def purify_volume(self) -> int: def motor_speed(self) -> int: """Speed of the motor.""" return self.data["motor1_speed"] + @property @sensor("Motor 2 Speed", unit="rpm", icon="mdi:fan") def motor2_speed(self) -> int | None: """Speed of the 2nd motor.""" return self.data["motor2_speed"] - @setting( + @property - @setting("Volume", setter_name="set_volume", unit="%", min_value=0, max_value=100, step=1, icon="mdi:volume-high") + @setting( + "Volume", + setter_name="set_volume", + unit="%", + min_value=0, + max_value=100, + step=1, + icon="mdi:volume-high", + ) def volume(self) -> int | None: """Volume of sound notifications [0-100].""" return self.data["volume"] + @property @sensor("Filter RFID Product ID", icon="mdi:barcode") def filter_rfid_product_id(self) -> str | None: """RFID product ID of installed filter.""" return self.data["rfid_product_id"] + @property @sensor("Filter RFID Tag", icon="mdi:barcode") def filter_rfid_tag(self) -> str | None: """RFID tag ID of installed filter.""" return self.data["rfid_tag"] + @property @sensor("Filter Type", icon="mdi:filter-outline") def filter_type(self) -> FilterType | None: @@ -306,18 +329,22 @@ def filter_type(self) -> FilterType | None: def learn_mode(self) -> bool: """Return True if Learn Mode is enabled.""" return self.data["act_sleep"] == "single" + @property @sensor("Sleep Time", unit="s", icon="mdi:sleep") def sleep_time(self) -> int | None: return self.data["sleep_time"] + @property @sensor("Sleep Mode Learn Count", icon="mdi:counter") def sleep_mode_learn_count(self) -> int | None: return self.data["sleep_data_num"] + @property @setting("Extra Features", setter_name="set_extra_features", icon="mdi:star") def extra_features(self) -> int | None: return self.data["app_extra"] + @property @sensor("Turbo Mode Supported", icon="mdi:rocket") def turbo_mode_supported(self) -> bool | None: @@ -325,6 +352,7 @@ def turbo_mode_supported(self) -> bool | None: return self.data["app_extra"] == 1 return None + @property @setting("Auto Detect", setter_name="set_auto_detect", icon="mdi:eye") def auto_detect(self) -> bool | None: @@ -333,6 +361,7 @@ def auto_detect(self) -> bool | None: return self.data["act_det"] == "on" return None + @property @sensor("Button Pressed", icon="mdi:gesture-tap-button") def button_pressed(self) -> str | None: diff --git a/miio/integrations/zhimi/heater/heater.py b/miio/integrations/zhimi/heater/heater.py index c1e4ac724..a005d0953 100644 --- a/miio/integrations/zhimi/heater/heater.py +++ b/miio/integrations/zhimi/heater/heater.py @@ -134,7 +134,8 @@ def use_time(self) -> int: @property @sensor( - @sensor("Delay Off Countdown", unit="s", icon="mdi:timer-sand", device_class="duration") + "Delay Off Countdown", unit="s", icon="mdi:timer-sand", device_class="duration" + ) def delay_off_countdown(self) -> int | None: """Countdown until turning off in seconds.""" if "poweroff_time" in self.data and self.data["poweroff_time"] is not None: diff --git a/miio/integrations/zhimi/heater/heater_miot.py b/miio/integrations/zhimi/heater/heater_miot.py index 2fb48268c..72f630e4b 100644 --- a/miio/integrations/zhimi/heater/heater_miot.py +++ b/miio/integrations/zhimi/heater/heater_miot.py @@ -165,7 +165,8 @@ def temperature(self) -> float: @property @sensor( - @sensor("Relative Humidity", unit="%", icon="mdi:water-percent", device_class="humidity") + "Relative Humidity", unit="%", icon="mdi:water-percent", device_class="humidity" + ) def relative_humidity(self) -> int | None: """Current relative humidity.""" return self.data.get("relative_humidity") From 1300bf779b7708324af97d90b2c60702ac64f149 Mon Sep 17 00:00:00 2001 From: Teemu Rytilahti Date: Sun, 5 Jul 2026 15:25:36 +0200 Subject: [PATCH 4/7] Remove icon= from @sensor and @setting decorators --- .../airdog/airpurifier/airpurifier_airdog.py | 14 ++-- .../cgllc/airmonitor/airqualitymonitor.py | 30 ++++--- .../airmonitor/airqualitymonitor_miot.py | 20 ++--- .../chuangmi/camera/chuangmi_camera.py | 30 +++---- .../chuangmi/plug/chuangmi_plug.py | 14 ++-- miio/integrations/chunmi/cooker/cooker.py | 84 +++++++++---------- .../deerma/humidifier/airhumidifier_jsqs.py | 21 ++--- .../deerma/humidifier/airhumidifier_mjjsq.py | 20 ++--- .../dmaker/airfresh/airfresh_t2017.py | 38 ++++----- miio/integrations/dmaker/fan/fan.py | 19 ++--- miio/integrations/dmaker/fan/fan_miot.py | 38 ++++----- .../dreame/vacuum/dreamevacuum_miot.py | 61 +++++++------- miio/integrations/huayi/light/huizuo.py | 14 ++-- .../ksmb/walkingpad/walkingpad.py | 16 ++-- miio/integrations/leshow/fan/fan_leshow.py | 13 ++- .../acpartner/airconditioningcompanion.py | 37 ++++---- .../acpartner/airconditioningcompanionMCN.py | 23 ++--- miio/integrations/lumi/camera/aqaracamera.py | 27 +++--- .../lumi/curtain/curtain_youpin.py | 18 ++-- miio/integrations/mijia/vacuum/g1vacuum.py | 43 +++++----- .../mmgg/petwaterdispenser/status.py | 24 +++--- .../nwt/dehumidifier/airdehumidifier.py | 27 +++--- miio/integrations/philips/light/ceil.py | 12 +-- .../philips/light/philips_bulb.py | 15 ++-- .../philips/light/philips_eyecare.py | 15 ++-- .../philips/light/philips_moonlight.py | 21 ++--- .../philips/light/philips_rwread.py | 14 +--- miio/integrations/pwzn/relay/pwzn_relay.py | 6 +- .../roidmi/vacuum/roidmivacuum_miot.py | 75 ++++++++--------- .../shuii/humidifier/airhumidifier_jsq.py | 18 ++-- .../tinymu/toiletlid/toiletlid.py | 10 +-- .../viomi/viomidishwasher/viomidishwasher.py | 21 +++-- .../aircondition/airconditioner_miot.py | 53 +++++------- .../xiaomi/repeater/wifirepeater.py | 10 +-- .../xiaomi/wifispeaker/wifispeaker.py | 18 ++-- .../dual_switch/yeelight_dual_switch.py | 14 ++-- .../yunmi/waterpurifier/waterpurifier.py | 38 ++++----- .../waterpurifier/waterpurifier_yunmi.py | 52 ++++++------ .../zhimi/airpurifier/airfresh.py | 47 +++++------ .../zhimi/airpurifier/airpurifier.py | 78 +++++++---------- miio/integrations/zhimi/fan/zhimi_miot.py | 34 ++++---- miio/integrations/zhimi/heater/heater.py | 22 ++--- miio/integrations/zhimi/heater/heater_miot.py | 22 ++--- miio/integrations/zimi/clock/alarmclock.py | 6 +- 44 files changed, 526 insertions(+), 706 deletions(-) diff --git a/miio/integrations/airdog/airpurifier/airpurifier_airdog.py b/miio/integrations/airdog/airpurifier/airpurifier_airdog.py index 5fa3479f7..a4180276b 100644 --- a/miio/integrations/airdog/airpurifier/airpurifier_airdog.py +++ b/miio/integrations/airdog/airpurifier/airpurifier_airdog.py @@ -49,13 +49,13 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @sensor("Power", icon="mdi:power") + @sensor("Power") def power(self) -> str: """Power state.""" return self.data["power"] @property - @sensor("Is On", icon="mdi:power") + @sensor("Is On") def is_on(self) -> bool: """True if device is turned on.""" return self.power == "on" @@ -64,7 +64,6 @@ def is_on(self) -> bool: @setting( "Mode", setter_name="set_mode_and_speed", - icon="mdi:fan", choices=OperationMode, ) def mode(self) -> OperationMode: @@ -78,7 +77,6 @@ def mode(self) -> OperationMode: @setting( "Speed", setter_name="set_mode_and_speed", - icon="mdi:speedometer", min_value=1, max_value=5, step=1, @@ -88,25 +86,25 @@ def speed(self) -> int: return self.data["speed"] @property - @setting("Child Lock", setter_name="set_child_lock", icon="mdi:lock") + @setting("Child Lock", setter_name="set_child_lock") def child_lock(self) -> bool: """Return True if child lock is on.""" return self.data["lock"] == "lock" @property - @sensor("Clean Filters", icon="mdi:air-filter") + @sensor("Clean Filters") def clean_filters(self) -> bool: """True if the display shows "-C-" and the filter must be cleaned.""" return self.data["clean"] == "y" @property - @sensor("PM2.5", unit="μg/m³", icon="mdi:blur", device_class="pm25") + @sensor("PM2.5", unit="μg/m³", device_class="pm25") def pm25(self) -> int: """Return particulate matter value (0...300μg/m³).""" return self.data["pm"] @property - @sensor("Formaldehyde", icon="mdi:chemical-weapon") + @sensor("Formaldehyde") def hcho(self) -> int | None: """Return formaldehyde value.""" if self.data["hcho"] is not None: diff --git a/miio/integrations/cgllc/airmonitor/airqualitymonitor.py b/miio/integrations/cgllc/airmonitor/airqualitymonitor.py index 518cb3497..1cc8ca81f 100644 --- a/miio/integrations/cgllc/airmonitor/airqualitymonitor.py +++ b/miio/integrations/cgllc/airmonitor/airqualitymonitor.py @@ -58,19 +58,19 @@ def __init__(self, data): self.data = data @property - @sensor("Power", icon="mdi:power") + @sensor("Power") def power(self) -> str | None: """Current power state.""" return self.data.get("power") @property - @sensor("Is On", icon="mdi:power") + @sensor("Is On") def is_on(self) -> bool: """Return True if the device is turned on.""" return self.power == "on" @property - @sensor("USB Power", icon="mdi:usb") + @sensor("USB Power") def usb_power(self) -> bool | None: """Return True if the device's usb is on.""" if "usb_state" in self.data and self.data["usb_state"] is not None: @@ -78,19 +78,19 @@ def usb_power(self) -> bool | None: return None @property - @sensor("AQI", icon="mdi:air-filter") + @sensor("AQI") def aqi(self) -> int | None: """Air quality index value (0..600).""" return self.data.get("aqi") @property - @sensor("Battery", unit="%", device_class="battery", icon="mdi:battery") + @sensor("Battery", unit="%", device_class="battery") def battery(self) -> int | None: """Current battery level (0..100).""" return self.data.get("battery") @property - @setting("Display Clock", setter_name="set_display_clock", icon="mdi:clock-outline") + @setting("Display Clock", setter_name="set_display_clock") def display_clock(self) -> bool | None: """Display a clock instead the AQI.""" if "time_state" in self.data and self.data["time_state"] is not None: @@ -98,7 +98,7 @@ def display_clock(self) -> bool | None: return None @property - @setting("Night Mode", setter_name="set_night_mode", icon="mdi:weather-night") + @setting("Night Mode", setter_name="set_night_mode") def night_mode(self) -> bool | None: """Return True if the night mode is on.""" if "night_state" in self.data and self.data["night_state"] is not None: @@ -106,19 +106,19 @@ def night_mode(self) -> bool | None: return None @property - @sensor("Night Time Begin", icon="mdi:clock-start") + @sensor("Night Time Begin") def night_time_begin(self) -> str | None: """Return the begin of the night time.""" return self.data.get("night_beg_time") @property - @sensor("Night Time End", icon="mdi:clock-end") + @sensor("Night Time End") def night_time_end(self) -> str | None: """Return the end of the night time.""" return self.data.get("night_end_time") @property - @sensor("Sensor State", icon="mdi:eye") + @sensor("Sensor State") def sensor_state(self) -> str | None: """Sensor state.""" return self.data.get("sensor_state") @@ -134,27 +134,25 @@ def co2e(self) -> int | None: return self.data.get("co2e") @property - @sensor("Humidity", unit="%", device_class="humidity", icon="mdi:water-percent") + @sensor("Humidity", unit="%", device_class="humidity") def humidity(self) -> float | None: """Return humidity value (0...100%).""" return self.data.get("humidity") @property - @sensor("PM2.5", unit="μg/m³", device_class="pm25", icon="mdi:blur") + @sensor("PM2.5", unit="μg/m³", device_class="pm25") def pm25(self) -> float | None: """Return pm2.5 value (0...999μg/m³).""" return self.data.get("pm25") @property - @sensor( - "Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer" - ) + @sensor("Temperature", unit="°C", device_class="temperature") def temperature(self) -> float | None: """Return temperature value (-10...50°C).""" return self.data.get("temperature") @property - @sensor("TVOC", icon="mdi:cloud") + @sensor("TVOC") def tvoc(self) -> int | None: """Return tvoc value.""" return self.data.get("tvoc") diff --git a/miio/integrations/cgllc/airmonitor/airqualitymonitor_miot.py b/miio/integrations/cgllc/airmonitor/airqualitymonitor_miot.py index c57a2502e..682a087d6 100644 --- a/miio/integrations/cgllc/airmonitor/airqualitymonitor_miot.py +++ b/miio/integrations/cgllc/airmonitor/airqualitymonitor_miot.py @@ -108,45 +108,43 @@ def __init__(self, data): self.data = data @property - @sensor("Humidity", unit="%", icon="mdi:water-percent", device_class="humidity") + @sensor("Humidity", unit="%", device_class="humidity") def humidity(self) -> int: """Return humidity value (0...100%).""" return self.data["humidity"] @property - @sensor("PM2.5", unit="µg/m³", icon="mdi:blur") + @sensor("PM2.5", unit="µg/m³") def pm25(self) -> int: """Return PM 2.5 value (0...1000ppm).""" return self.data["pm25"] @property - @sensor("PM10", unit="µg/m³", icon="mdi:blur-linear") + @sensor("PM10", unit="µg/m³") def pm10(self) -> int: """Return PM 10 value (0...1000ppm).""" return self.data["pm10"] @property - @sensor( - "Temperature", unit="°C", icon="mdi:thermometer", device_class="temperature" - ) + @sensor("Temperature", unit="°C", device_class="temperature") def temperature(self) -> float: """Return temperature value (-30...100°C).""" return self.data["temperature"] @property - @sensor("CO2", unit="ppm", icon="mdi:molecule-co2", device_class="carbon_dioxide") + @sensor("CO2", unit="ppm", device_class="carbon_dioxide") def co2(self) -> int: """Return co2 value (0...9999ppm).""" return self.data["co2"] @property - @sensor("Battery", unit="%", icon="mdi:battery", device_class="battery") + @sensor("Battery", unit="%", device_class="battery") def battery(self) -> int: """Return battery level (0...100%).""" return self.data["battery"] @property - @sensor("Charging State", icon="mdi:battery-charging") + @sensor("Charging State") def charging_state(self) -> ChargingState: """Return charging state.""" return ChargingState(self.data["charging_state"]) @@ -158,7 +156,6 @@ def charging_state(self) -> ChargingState: setter_name="set_monitoring_frequency_duration", min_value=0, max_value=600, - icon="mdi:update", ) def monitoring_frequency(self) -> int: """Return monitoring frequency time (0..600 s).""" @@ -171,7 +168,6 @@ def monitoring_frequency(self) -> int: setter_name="set_screen_off_duration", min_value=0, max_value=300, - icon="mdi:monitor-off", ) def screen_off(self) -> int: """Return screen off time (0..300 s).""" @@ -184,7 +180,6 @@ def screen_off(self) -> int: setter_name="set_device_off_duration", min_value=0, max_value=60, - icon="mdi:power-off", ) def device_off(self) -> int: """Return device off time (0..60 min).""" @@ -195,7 +190,6 @@ def device_off(self) -> int: "Display Temperature Unit", setter_name="set_display_temperature_unit", choices=DisplayTemperatureUnitCGDN1, - icon="mdi:temperature-celsius", ) def display_temperature_unit(self) -> DisplayTemperatureUnitCGDN1: """Return display temperature unit.""" diff --git a/miio/integrations/chuangmi/camera/chuangmi_camera.py b/miio/integrations/chuangmi/camera/chuangmi_camera.py index 5647a26b0..ae61c272b 100644 --- a/miio/integrations/chuangmi/camera/chuangmi_camera.py +++ b/miio/integrations/chuangmi/camera/chuangmi_camera.py @@ -92,83 +92,79 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @setting(name="Power", setter_name="on", icon="mdi:power") + @setting(name="Power", setter_name="on") def power(self) -> bool: """Camera power.""" return self.data["power"] == "on" @property - @setting( - name="Motion Record", setter_name="motion_record_on", icon="mdi:motion-sensor" - ) + @setting(name="Motion Record", setter_name="motion_record_on") def motion_record(self) -> bool: """Motion record status.""" return self.data["motion_record"] == "on" @property - @setting(name="Light", setter_name="light_on", icon="mdi:lightbulb") + @setting(name="Light", setter_name="light_on") def light(self) -> bool: """Camera light status.""" return self.data["light"] == "on" @property - @setting(name="Full Color", setter_name="full_color_on", icon="mdi:palette") + @setting(name="Full Color", setter_name="full_color_on") def full_color(self) -> bool: """Full color with bad lighting conditions.""" return self.data["full_color"] == "on" @property - @setting(name="Flip", setter_name="flip_on", icon="mdi:flip-vertical") + @setting(name="Flip", setter_name="flip_on") def flip(self) -> bool: """Image 180 degrees flip status.""" return self.data["flip"] == "on" @property - @setting( - name="Improve Program", setter_name="improve_program_on", icon="mdi:chart-line" - ) + @setting(name="Improve Program", setter_name="improve_program_on") def improve_program(self) -> bool: """Customer experience improvement program status.""" return self.data["improve_program"] == "on" @property - @setting(name="WDR", setter_name="wdr_on", icon="mdi:contrast-box") + @setting(name="WDR", setter_name="wdr_on") def wdr(self) -> bool: """Wide dynamic range status.""" return self.data["wdr"] == "on" @property - @sensor(name="Track", icon="mdi:crosshairs-gps") + @sensor(name="Track") def track(self) -> bool: """Tracking status.""" return self.data["track"] == "on" @property - @setting(name="Watermark", setter_name="watermark_on", icon="mdi:watermark") + @setting(name="Watermark", setter_name="watermark_on") def watermark(self) -> bool: """Apply watermark to video.""" return self.data["watermark"] == "on" @property - @sensor(name="SD Card Status", icon="mdi:sd") + @sensor(name="SD Card Status") def sdcard_status(self) -> int: """SD card status.""" return self.data["sdcard_status"] @property - @sensor(name="Max Client", icon="mdi:account-multiple") + @sensor(name="Max Client") def max_client(self) -> int: """Unknown.""" return self.data["max_client"] @property - @sensor(name="Night Mode", icon="mdi:weather-night") + @sensor(name="Night Mode") def night_mode(self) -> int: """Night mode.""" return self.data["night_mode"] @property - @sensor(name="Mini Level", icon="mdi:volume-low") + @sensor(name="Mini Level") def mini_level(self) -> int: """Unknown.""" return self.data["mini_level"] diff --git a/miio/integrations/chuangmi/plug/chuangmi_plug.py b/miio/integrations/chuangmi/plug/chuangmi_plug.py index 27dac997a..bc21ba27e 100644 --- a/miio/integrations/chuangmi/plug/chuangmi_plug.py +++ b/miio/integrations/chuangmi/plug/chuangmi_plug.py @@ -46,7 +46,7 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @sensor("Power", icon="mdi:power-plug") + @sensor("Power") def power(self) -> bool: """Current power state.""" if "on" in self.data: @@ -57,20 +57,18 @@ def power(self) -> bool: raise DeviceException("There was neither 'on' or 'power' in data") @property - @setting("Power", setter_name="on", icon="mdi:power-plug") + @setting("Power", setter_name="on") def is_on(self) -> bool: """True if device is on.""" return self.power @property - @sensor( - "Temperature", unit="°C", icon="mdi:thermometer", device_class="temperature" - ) + @sensor("Temperature", unit="°C", device_class="temperature") def temperature(self) -> int: return self.data["temperature"] @property - @setting("USB Power", setter_name="usb_on", icon="mdi:usb") + @setting("USB Power", setter_name="usb_on") def usb_power(self) -> bool | None: """True if USB is on.""" if "usb_on" in self.data and self.data["usb_on"] is not None: @@ -78,7 +76,7 @@ def usb_power(self) -> bool | None: return None @property - @sensor("Load Power", unit="W", icon="mdi:flash", device_class="power") + @sensor("Load Power", unit="W", device_class="power") def load_power(self) -> float | None: """Current power load, if available.""" if "load_power" in self.data and self.data["load_power"] is not None: @@ -92,7 +90,7 @@ def wifi_led(self) -> bool | None: return self.led @property - @setting("LED", setter_name="set_led", icon="mdi:led-on") + @setting("LED", setter_name="set_led") def led(self) -> bool | None: """True if the wifi led is turned on.""" if "wifi_led" in self.data and self.data["wifi_led"] is not None: diff --git a/miio/integrations/chunmi/cooker/cooker.py b/miio/integrations/chunmi/cooker/cooker.py index b7462d9b3..173ed5543 100644 --- a/miio/integrations/chunmi/cooker/cooker.py +++ b/miio/integrations/chunmi/cooker/cooker.py @@ -126,12 +126,12 @@ def __init__(self, data: str): self.data = [] @property - @sensor("Temperatures", unit="°C", icon="mdi:thermometer") + @sensor("Temperatures", unit="°C") def temperatures(self) -> list[int]: return self.data @property - @sensor("Raw", icon="mdi:code-string") + @sensor("Raw") def raw(self) -> str: return "".join([f"{value:02x}" for value in self.data]) @@ -167,32 +167,32 @@ def __init__(self, custom: str): self.custom = [int(custom[i : i + 2], 16) for i in range(0, len(custom), 2)] @property - @sensor("Jingzhu Appointment", icon="mdi:clock-outline") + @sensor("Jingzhu Appointment") def jingzhu_appointment(self) -> time: return time(hour=self.custom[0], minute=self.custom[1]) @property - @sensor("Kuaizhu Appointment", icon="mdi:clock-outline") + @sensor("Kuaizhu Appointment") def kuaizhu_appointment(self) -> time: return time(hour=self.custom[2], minute=self.custom[3]) @property - @sensor("Zhuzhou Appointment", icon="mdi:clock-outline") + @sensor("Zhuzhou Appointment") def zhuzhou_appointment(self) -> time: return time(hour=self.custom[4], minute=self.custom[5]) @property - @sensor("Zhuzhou Cooking", icon="mdi:clock-outline") + @sensor("Zhuzhou Cooking") def zhuzhou_cooking(self) -> time: return time(hour=self.custom[6], minute=self.custom[7]) @property - @sensor("Favorite Appointment", icon="mdi:clock-outline") + @sensor("Favorite Appointment") def favorite_appointment(self) -> time: return time(hour=self.custom[8], minute=self.custom[9]) @property - @sensor("Favorite Cooking", icon="mdi:clock-outline") + @sensor("Favorite Cooking") def favorite_cooking(self) -> time: return time(hour=self.custom[10], minute=self.custom[11]) @@ -216,7 +216,7 @@ def __init__(self, stage: str): self.stage = stage @property - @sensor("State", icon="mdi:pot-steam") + @sensor("State") def state(self) -> int: """ @@ -227,17 +227,17 @@ def state(self) -> int: return int(self.stage[0:2], 16) @property - @sensor("Rice ID", icon="mdi:rice") + @sensor("Rice ID") def rice_id(self) -> int: return int(self.stage[2:6], 16) @property - @sensor("Taste", icon="mdi:food-variant") + @sensor("Taste") def taste(self) -> int: return int(self.stage[6:8], 16) @property - @sensor("Taste Phase", icon="mdi:food-variant") + @sensor("Taste Phase") def taste_phase(self) -> int: phase = int(self.taste / 33) @@ -246,7 +246,7 @@ def taste_phase(self) -> int: return phase @property - @sensor("Name", icon="mdi:label") + @sensor("Name") def name(self) -> str: try: return COOKING_STAGES[self.state]["name"] @@ -254,7 +254,7 @@ def name(self) -> str: return "Unknown stage" @property - @sensor("Description", icon="mdi:text") + @sensor("Description") def description(self) -> str: try: return COOKING_STAGES[self.state]["description"] @@ -262,7 +262,7 @@ def description(self) -> str: return "" @property - @sensor("Raw", icon="mdi:code-string") + @sensor("Raw") def raw(self) -> str: return self.stage @@ -285,7 +285,7 @@ def __init__(self, timeouts: str | None = None): ] @property - @sensor("LED Off Timeout", unit="s", icon="mdi:led-off") + @sensor("LED Off Timeout", unit="s") def led_off(self) -> int: return self.timeouts[0] @@ -294,7 +294,7 @@ def led_off(self, delay: int): self.timeouts[0] = delay @property - @sensor("Lid Open Timeout", unit="s", icon="mdi:pot-steam-outline") + @sensor("Lid Open Timeout", unit="s") def lid_open(self) -> int: return self.timeouts[1] @@ -303,7 +303,7 @@ def lid_open(self, timeout: int): self.timeouts[1] = timeout @property - @sensor("Lid Open Warning Timeout", unit="s", icon="mdi:alert") + @sensor("Lid Open Warning Timeout", unit="s") def lid_open_warning(self) -> int: return self.timeouts[2] @@ -343,7 +343,7 @@ def __init__(self, settings: str | None = None): ] @property - @sensor("Pressure Supported", icon="mdi:gauge") + @sensor("Pressure Supported") def pressure_supported(self) -> bool: return self._settings[0] & 1 != 0 @@ -355,7 +355,7 @@ def pressure_supported(self, supported: bool): self._settings[0] &= 254 @property - @sensor("LED On", icon="mdi:led-on") + @sensor("LED On") def led_on(self) -> bool: return self._settings[0] & 2 != 0 @@ -367,7 +367,7 @@ def led_on(self, on: bool): self._settings[0] &= 253 @property - @sensor("Auto Keep Warm", icon="mdi:pot-steam") + @sensor("Auto Keep Warm") def auto_keep_warm(self) -> bool: return self._settings[0] & 4 != 0 @@ -379,7 +379,7 @@ def auto_keep_warm(self, keep_warm: bool): self._settings[0] &= 251 @property - @sensor("Lid Open Warning", icon="mdi:alert") + @sensor("Lid Open Warning") def lid_open_warning(self) -> bool: return self._settings[0] & 8 != 0 @@ -391,7 +391,7 @@ def lid_open_warning(self, alarm: bool): self._settings[0] &= 247 @property - @sensor("Lid Open Warning Delayed", icon="mdi:alert-outline") + @sensor("Lid Open Warning Delayed") def lid_open_warning_delayed(self) -> bool: return self._settings[0] & 16 != 0 @@ -403,7 +403,7 @@ def lid_open_warning_delayed(self, alarm: bool): self._settings[0] &= 239 @property - @sensor("Jingzhu Auto Keep Warm", icon="mdi:pot-steam") + @sensor("Jingzhu Auto Keep Warm") def jingzhu_auto_keep_warm(self) -> bool: return self._settings[1] & 1 != 0 @@ -415,7 +415,7 @@ def jingzhu_auto_keep_warm(self, auto_keep_warm: bool): self._settings[1] &= 254 @property - @sensor("Kuaizhu Auto Keep Warm", icon="mdi:pot-steam") + @sensor("Kuaizhu Auto Keep Warm") def kuaizhu_auto_keep_warm(self) -> bool: return self._settings[1] & 2 != 0 @@ -427,7 +427,7 @@ def kuaizhu_auto_keep_warm(self, auto_keep_warm: bool): self._settings[1] &= 253 @property - @sensor("Zhuzhou Auto Keep Warm", icon="mdi:pot-steam") + @sensor("Zhuzhou Auto Keep Warm") def zhuzhou_auto_keep_warm(self) -> bool: return self._settings[1] & 4 != 0 @@ -439,7 +439,7 @@ def zhuzhou_auto_keep_warm(self, auto_keep_warm: bool): self._settings[1] &= 251 @property - @sensor("Favorite Auto Keep Warm", icon="mdi:pot-steam") + @sensor("Favorite Auto Keep Warm") def favorite_auto_keep_warm(self) -> bool: return self._settings[1] & 8 != 0 @@ -498,19 +498,19 @@ def __init__(self, data): self.data = data @property - @sensor("Mode", icon="mdi:pot-steam") + @sensor("Mode") def mode(self) -> OperationMode: """Current operation mode.""" return OperationMode(self.data["func"]) @property - @sensor("Menu", icon="mdi:book-open-variant") + @sensor("Menu") def menu(self) -> int: """Selected recipe id.""" return int(self.data["menu"], 16) @property - @sensor("Stage", icon="mdi:pot-steam") + @sensor("Stage") def stage(self) -> CookingStage | None: """Current stage if cooking.""" stage = self.data["stage"] @@ -520,9 +520,7 @@ def stage(self) -> CookingStage | None: return None @property - @sensor( - "Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer" - ) + @sensor("Temperature", unit="°C", device_class="temperature") def temperature(self) -> int | None: """Current temperature, if idle. @@ -535,7 +533,7 @@ def temperature(self) -> int | None: return None @property - @sensor("Start Time", icon="mdi:clock-start") + @sensor("Start Time") def start_time(self) -> time | None: """Start time of cooking? @@ -549,13 +547,13 @@ def start_time(self) -> time | None: return None @property - @sensor("Remaining", unit="min", icon="mdi:timer-outline") + @sensor("Remaining", unit="min") def remaining(self) -> int: """Remaining minutes of the cooking process.""" return int(self.data["t_func"]) @property - @sensor("Cooking Delayed", unit="min", icon="mdi:timer-sand") + @sensor("Cooking Delayed", unit="min") def cooking_delayed(self) -> int | None: """Wait n minutes before cooking / scheduled cooking.""" delay = int(self.data["t_precook"]) @@ -566,37 +564,37 @@ def cooking_delayed(self) -> int | None: return None @property - @sensor("Duration", unit="min", icon="mdi:timer-outline") + @sensor("Duration", unit="min") def duration(self) -> int: """Duration of the cooking process.""" return int(self.data["t_cook"]) @property - @sensor("Cooker Settings", icon="mdi:cog") + @sensor("Cooker Settings") def cooker_settings(self) -> CookerSettings: """Settings of the cooker.""" return CookerSettings(self.data["setting"]) @property - @sensor("Interaction Timeouts", icon="mdi:timer-cog-outline") + @sensor("Interaction Timeouts") def interaction_timeouts(self) -> InteractionTimeouts: """Interaction timeouts.""" return InteractionTimeouts(self.data["delay"]) @property - @sensor("Hardware Version", icon="mdi:chip") + @sensor("Hardware Version") def hardware_version(self) -> int: """Hardware version.""" return int(self.data["version"][0:4], 16) @property - @sensor("Firmware Version", icon="mdi:update") + @sensor("Firmware Version") def firmware_version(self) -> int: """Firmware version.""" return int(self.data["version"][4:8], 16) @property - @sensor("Favorite", icon="mdi:star") + @sensor("Favorite") def favorite(self) -> int: """Favored recipe id. @@ -605,7 +603,7 @@ def favorite(self) -> int: return int(self.data["favorite"], 16) @property - @sensor("Custom", icon="mdi:tune") + @sensor("Custom") def custom(self) -> CookerCustomizations | None: custom = self.data["custom"] diff --git a/miio/integrations/deerma/humidifier/airhumidifier_jsqs.py b/miio/integrations/deerma/humidifier/airhumidifier_jsqs.py index 1f3ce5c43..4ed660205 100644 --- a/miio/integrations/deerma/humidifier/airhumidifier_jsqs.py +++ b/miio/integrations/deerma/humidifier/airhumidifier_jsqs.py @@ -70,19 +70,19 @@ def __init__(self, data: dict[str, Any]) -> None: # Air Humidifier @property - @setting(name="Power", setter_name="on", icon="mdi:power") + @setting(name="Power", setter_name="on") def is_on(self) -> bool: """Return True if device is on.""" return self.data["power"] @property - @sensor(name="Power", icon="mdi:power") + @sensor(name="Power") def power(self) -> str: """Return power state.""" return "on" if self.is_on else "off" @property - @sensor(name="Error", icon="mdi:alert-circle") + @sensor(name="Error") def error(self) -> int: """Return error state.""" return self.data["fault"] @@ -91,7 +91,6 @@ def error(self) -> int: @setting( name="Mode", setter_name="set_mode", - icon="mdi:fan", choices=OperationMode, ) def mode(self) -> OperationMode: @@ -127,7 +126,7 @@ def temperature(self) -> float | None: # Alarm @property - @setting(name="Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") + @setting(name="Buzzer", setter_name="set_buzzer") def buzzer(self) -> bool | None: """Return True if buzzer is on.""" return self.data.get("buzzer") @@ -135,7 +134,7 @@ def buzzer(self) -> bool | None: # Indicator Light @property - @setting(name="LED Light", setter_name="set_light", icon="mdi:led-outline") + @setting(name="LED Light", setter_name="set_light") def led_light(self) -> bool | None: """Return status of the LED.""" return self.data.get("led_light") @@ -143,23 +142,19 @@ def led_light(self) -> bool | None: # Other @property - @sensor(name="Tank Filed", icon="mdi:cup-water") + @sensor(name="Tank Filed") def tank_filed(self) -> bool | None: """Return the tank filed.""" return self.data.get("tank_filed") @property - @sensor(name="Water Shortage Fault", icon="mdi:water-off") + @sensor(name="Water Shortage Fault") def water_shortage_fault(self) -> bool | None: """Return water shortage fault.""" return self.data.get("water_shortage_fault") @property - @setting( - name="Overwet Protect", - setter_name="set_overwet_protect", - icon="mdi:shield-check", - ) + @setting(name="Overwet Protect", setter_name="set_overwet_protect") def overwet_protect(self) -> bool | None: """Return True if overwet mode is active.""" return self.data.get("overwet_protect") diff --git a/miio/integrations/deerma/humidifier/airhumidifier_mjjsq.py b/miio/integrations/deerma/humidifier/airhumidifier_mjjsq.py index 10889824f..adef09017 100644 --- a/miio/integrations/deerma/humidifier/airhumidifier_mjjsq.py +++ b/miio/integrations/deerma/humidifier/airhumidifier_mjjsq.py @@ -56,13 +56,13 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @sensor(name="Power", icon="mdi:power") + @sensor(name="Power") def power(self) -> str: """Power state.""" return "on" if self.data["OnOff_State"] == 1 else "off" @property - @setting(name="Power", setter_name="on", icon="mdi:power") + @setting(name="Power", setter_name="on") def is_on(self) -> bool: """True if device is turned on.""" return self.power == "on" @@ -71,7 +71,6 @@ def is_on(self) -> bool: @setting( name="Mode", setter_name="set_mode", - icon="mdi:fan", choices=OperationMode, ) def mode(self) -> OperationMode: @@ -94,13 +93,13 @@ def humidity(self) -> int: return self.data["Humidity_Value"] @property - @setting(name="Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") + @setting(name="Buzzer", setter_name="set_buzzer") def buzzer(self) -> bool: """True if buzzer is turned on.""" return self.data["TipSound_State"] == 1 @property - @setting(name="LED", setter_name="set_led", icon="mdi:led-outline") + @setting(name="LED", setter_name="set_led") def led(self) -> bool: """True if LED is turned on.""" return self.data["Led_State"] == 1 @@ -110,7 +109,6 @@ def led(self) -> bool: name="Target Humidity", setter_name="set_target_humidity", unit="%", - icon="mdi:water-percent", min_value=0, max_value=99, ) @@ -119,21 +117,19 @@ def target_humidity(self) -> int: return self.data["HumiSet_Value"] @property - @sensor(name="No Water", icon="mdi:water-off") + @sensor(name="No Water") def no_water(self) -> bool: """True if the water tank is empty.""" return self.data["waterstatus"] == 0 @property - @sensor(name="Water Tank Detached", icon="mdi:cup-water") + @sensor(name="Water Tank Detached") def water_tank_detached(self) -> bool: """True if the water tank is detached.""" return self.data["watertankstatus"] == 0 @property - @setting( - name="Wet Protection", setter_name="set_wet_protection", icon="mdi:shield-check" - ) + @setting(name="Wet Protection", setter_name="set_wet_protection") def wet_protection(self) -> bool | None: """True if wet protection is enabled.""" if self.data["wet_and_protect"] is not None: @@ -142,7 +138,7 @@ def wet_protection(self) -> bool | None: return None @property - @sensor(name="Use Time", unit="s", icon="mdi:timer") + @sensor(name="Use Time", unit="s") def use_time(self) -> int | None: """How long the device has been active in seconds. diff --git a/miio/integrations/dmaker/airfresh/airfresh_t2017.py b/miio/integrations/dmaker/airfresh/airfresh_t2017.py index ab2e66754..16a9158e0 100644 --- a/miio/integrations/dmaker/airfresh/airfresh_t2017.py +++ b/miio/integrations/dmaker/airfresh/airfresh_t2017.py @@ -116,25 +116,25 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @sensor("Power", icon="mdi:power") + @sensor("Power") def power(self) -> str: """Power state.""" return "on" if self.data["power"] else "off" @property - @sensor("Is On", icon="mdi:power") + @sensor("Is On") def is_on(self) -> bool: """Return True if device is on.""" return self.data["power"] @property - @setting("Mode", setter_name="set_mode", choices=OperationMode, icon="mdi:fan") + @setting("Mode", setter_name="set_mode", choices=OperationMode) def mode(self) -> OperationMode: """Current operation mode.""" return OperationMode(self.data["mode"]) @property - @sensor("PM2.5", unit="μg/m³", device_class="pm25", icon="mdi:blur") + @sensor("PM2.5", unit="μg/m³", device_class="pm25") def pm25(self) -> int: """Fine particulate patter (PM2.5).""" return self.data["pm25"] @@ -144,16 +144,13 @@ def pm25(self) -> int: "CO2", unit="ppm", device_class="carbon_dioxide", - icon="mdi:molecule-co2", ) def co2(self) -> int: """Carbon dioxide.""" return self.data["co2"] @property - @sensor( - "Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer" - ) + @sensor("Temperature", unit="°C", device_class="temperature") def temperature(self) -> int: """Current temperature in degree celsions.""" return self.data["temperature_outside"] @@ -164,52 +161,49 @@ def temperature(self) -> int: setter_name="set_favorite_speed", min_value=0, max_value=150, - icon="mdi:fan", ) def favorite_speed(self) -> int: """Favorite speed.""" return self.data["favourite_speed"] @property - @sensor("Control Speed", icon="mdi:fan") + @sensor("Control Speed") def control_speed(self) -> int: """Control speed.""" return self.data["control_speed"] @property - @sensor("Dust Filter Life Remaining", unit="%", icon="mdi:filter") + @sensor("Dust Filter Life Remaining", unit="%") def dust_filter_life_remaining(self) -> int | None: """Remaining dust filter life in percent.""" return self.data.get("filter_intermediate", self.data.get("filter_rate")) @property - @sensor("Dust Filter Life Remaining Days", unit="days", icon="mdi:filter") + @sensor("Dust Filter Life Remaining Days", unit="days") def dust_filter_life_remaining_days(self) -> int | None: """Remaining dust filter life in days.""" return self.data.get("filter_inter_day", self.data.get("filter_day")) @property - @sensor("Upper Filter Life Remaining", unit="%", icon="mdi:filter") + @sensor("Upper Filter Life Remaining", unit="%") def upper_filter_life_remaining(self) -> int | None: """Remaining upper filter life in percent.""" return self.data.get("filter_efficient") @property - @sensor("Upper Filter Life Remaining Days", unit="days", icon="mdi:filter") + @sensor("Upper Filter Life Remaining Days", unit="days") def upper_filter_life_remaining_days(self) -> int | None: """Remaining upper filter life in days.""" return self.data.get("filter_effi_day") @property - @setting("PTC", setter_name="set_ptc", icon="mdi:radiator") + @setting("PTC", setter_name="set_ptc") def ptc(self) -> bool: """Return True if PTC is on.""" return self.data["ptc_on"] @property - @setting( - "PTC Level", setter_name="set_ptc_level", choices=PtcLevel, icon="mdi:radiator" - ) + @setting("PTC Level", setter_name="set_ptc_level", choices=PtcLevel) def ptc_level(self) -> PtcLevel | None: """PTC level.""" try: @@ -218,25 +212,25 @@ def ptc_level(self) -> PtcLevel | None: return None @property - @sensor("PTC Status", icon="mdi:radiator") + @sensor("PTC Status") def ptc_status(self) -> bool: """Return true if PTC status is on.""" return self.data["ptc_status"] @property - @setting("Child Lock", setter_name="set_child_lock", icon="mdi:lock") + @setting("Child Lock", setter_name="set_child_lock") def child_lock(self) -> bool: """Return True if child lock is on.""" return self.data["child_lock"] @property - @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") + @setting("Buzzer", setter_name="set_buzzer") def buzzer(self) -> bool: """Return True if sound is on.""" return self.data["sound"] @property - @setting("Display", setter_name="set_display", icon="mdi:monitor") + @setting("Display", setter_name="set_display") def display(self) -> bool: """Return True if the display is on.""" return self.data["display"] diff --git a/miio/integrations/dmaker/fan/fan.py b/miio/integrations/dmaker/fan/fan.py index 0f419c2d1..3543923a2 100644 --- a/miio/integrations/dmaker/fan/fan.py +++ b/miio/integrations/dmaker/fan/fan.py @@ -50,13 +50,13 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @sensor("Power", icon="mdi:power") + @sensor("Power") def power(self) -> str: """Power state.""" return "on" if self.data["power"] else "off" @property - @sensor("Is On", icon="mdi:power") + @sensor("Is On") def is_on(self) -> bool: """True if device is currently on.""" return self.data["power"] @@ -66,7 +66,6 @@ def is_on(self) -> bool: "Mode", setter_name="set_mode", choices=OperationMode, - icon="mdi:fan", ) def mode(self) -> OperationMode: """Operation mode.""" @@ -79,14 +78,13 @@ def mode(self) -> OperationMode: setter_name="set_speed", min_value=0, max_value=100, - icon="mdi:speedometer", ) def speed(self) -> int: """Speed of the motor.""" return self.data["speed"] @property - @setting("Oscillate", setter_name="set_oscillate", icon="mdi:sync") + @setting("Oscillate", setter_name="set_oscillate") def oscillate(self) -> bool: """True if oscillation is enabled.""" return self.data["roll_enable"] @@ -98,34 +96,31 @@ def oscillate(self) -> bool: setter_name="set_angle", min_value=30, max_value=140, - icon="mdi:angle-acute", ) def angle(self) -> int: """Oscillation angle.""" return self.data["roll_angle"] @property - @sensor( - "Delay Off Countdown", unit="s", icon="mdi:timer-sand", device_class="duration" - ) + @sensor("Delay Off Countdown", unit="s", device_class="duration") def delay_off_countdown(self) -> int: """Countdown until turning off in seconds.""" return self.data["time_off"] @property - @setting("LED", setter_name="set_led", icon="mdi:led-on") + @setting("LED", setter_name="set_led") def led(self) -> bool: """True if LED is turned on, if available.""" return self.data["light"] @property - @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") + @setting("Buzzer", setter_name="set_buzzer") def buzzer(self) -> bool: """True if buzzer is turned on.""" return self.data["beep_sound"] @property - @setting("Child Lock", setter_name="set_child_lock", icon="mdi:lock") + @setting("Child Lock", setter_name="set_child_lock") def child_lock(self) -> bool: """True if child lock is on.""" return self.data["child_lock"] diff --git a/miio/integrations/dmaker/fan/fan_miot.py b/miio/integrations/dmaker/fan/fan_miot.py index d76afd777..9a192d266 100644 --- a/miio/integrations/dmaker/fan/fan_miot.py +++ b/miio/integrations/dmaker/fan/fan_miot.py @@ -190,19 +190,19 @@ def __init__(self, data: dict[str, Any], model: str) -> None: self.model = model @property - @sensor("Power", icon="mdi:power") + @sensor("Power") def power(self) -> str: """Power state.""" return "on" if self.data["power"] else "off" @property - @sensor("Is On", icon="mdi:power") + @sensor("Is On") def is_on(self) -> bool: """True if device is currently on.""" return self.data["power"] @property - @setting("Mode", setter_name="set_mode", choices=OperationMode, icon="mdi:fan") + @setting("Mode", setter_name="set_mode", choices=OperationMode) def mode(self) -> OperationMode: """Operation mode.""" if self.model == MODEL_FAN_P45: @@ -210,21 +210,19 @@ def mode(self) -> OperationMode: return OperationMode[OperationModeMiot(self.data["mode"]).name] @property - @setting( - "Speed", setter_name="set_speed", min_value=0, max_value=100, icon="mdi:fan" - ) + @setting("Speed", setter_name="set_speed", min_value=0, max_value=100) def speed(self) -> int: """Speed of the motor.""" return self.data["fan_speed"] @property - @setting("Oscillate", setter_name="set_oscillate", icon="mdi:arrow-oscillating") + @setting("Oscillate", setter_name="set_oscillate") def oscillate(self) -> bool: """True if oscillation is enabled.""" return self.data["swing_mode"] @property - @setting("Angle", setter_name="set_angle", icon="mdi:angle-acute") + @setting("Angle", setter_name="set_angle") def angle(self) -> int: """Oscillation angle.""" return self.data["swing_mode_angle"] @@ -236,26 +234,25 @@ def angle(self) -> int: unit="min", min_value=0, max_value=480, - icon="mdi:timer", ) def delay_off_countdown(self) -> int: """Countdown until turning off in minutes.""" return self.data["power_off_time"] @property - @setting("LED", setter_name="set_led", icon="mdi:led-on") + @setting("LED", setter_name="set_led") def led(self) -> bool: """True if LED is turned on, if available.""" return self.data["light"] @property - @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") + @setting("Buzzer", setter_name="set_buzzer") def buzzer(self) -> bool: """True if buzzer is turned on.""" return self.data["buzzer"] @property - @setting("Child Lock", setter_name="set_child_lock", icon="mdi:lock") + @setting("Child Lock", setter_name="set_child_lock") def child_lock(self) -> bool: """True if child lock is on.""" return self.data["child_lock"] @@ -285,31 +282,31 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @sensor("Power", icon="mdi:power") + @sensor("Power") def power(self) -> str: """Power state.""" return "on" if self.data["power"] else "off" @property - @sensor("Is On", icon="mdi:power") + @sensor("Is On") def is_on(self) -> bool: """True if device is currently on.""" return self.data["power"] @property - @setting("Mode", setter_name="set_mode", choices=OperationMode, icon="mdi:fan") + @setting("Mode", setter_name="set_mode", choices=OperationMode) def mode(self) -> OperationMode: """Operation mode.""" return OperationMode[OperationModeMiot(self.data["mode"]).name] @property - @setting("Speed", setter_name="set_speed", min_value=1, max_value=3, icon="mdi:fan") + @setting("Speed", setter_name="set_speed", min_value=1, max_value=3) def speed(self) -> int: """Speed of the motor.""" return self.data["fan_level"] @property - @setting("Oscillate", setter_name="set_oscillate", icon="mdi:arrow-oscillating") + @setting("Oscillate", setter_name="set_oscillate") def oscillate(self) -> bool: """True if oscillation is enabled.""" return self.data["swing_mode"] @@ -321,26 +318,25 @@ def oscillate(self) -> bool: unit="min", min_value=0, max_value=480, - icon="mdi:timer", ) def delay_off_countdown(self) -> int: """Countdown until turning off in minutes.""" return self.data["power_off_time"] @property - @setting("LED", setter_name="set_led", icon="mdi:led-on") + @setting("LED", setter_name="set_led") def led(self) -> bool: """True if LED is turned on.""" return self.data["light"] @property - @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") + @setting("Buzzer", setter_name="set_buzzer") def buzzer(self) -> bool: """True if buzzer is turned on.""" return self.data["buzzer"] @property - @setting("Child Lock", setter_name="set_child_lock", icon="mdi:lock") + @setting("Child Lock", setter_name="set_child_lock") def child_lock(self) -> bool: """True if child lock is on.""" return self.data["child_lock"] diff --git a/miio/integrations/dreame/vacuum/dreamevacuum_miot.py b/miio/integrations/dreame/vacuum/dreamevacuum_miot.py index 8c21bd46e..78fb2c8d2 100644 --- a/miio/integrations/dreame/vacuum/dreamevacuum_miot.py +++ b/miio/integrations/dreame/vacuum/dreamevacuum_miot.py @@ -306,42 +306,42 @@ def __init__(self, data, model): self.model = model @property - @sensor("Battery Level", unit="%", device_class="battery", icon="mdi:battery") + @sensor("Battery Level", unit="%", device_class="battery") def battery_level(self) -> str: return self.data["battery_level"] @property - @sensor("Brush Left Time", unit="h", icon="mdi:brush") + @sensor("Brush Left Time", unit="h") def brush_left_time(self) -> str: return self.data["brush_left_time"] @property - @sensor("Side Brush Left Time", unit="h", icon="mdi:brush") + @sensor("Side Brush Left Time", unit="h") def brush_left_time2(self) -> str: return self.data["brush_left_time2"] @property - @sensor("Side Brush Life Level", unit="%", icon="mdi:brush") + @sensor("Side Brush Life Level", unit="%") def brush_life_level2(self) -> str: return self.data["brush_life_level2"] @property - @sensor("Brush Life Level", unit="%", icon="mdi:brush") + @sensor("Brush Life Level", unit="%") def brush_life_level(self) -> str: return self.data["brush_life_level"] @property - @sensor("Filter Left Time", unit="h", icon="mdi:filter-outline") + @sensor("Filter Left Time", unit="h") def filter_left_time(self) -> str: return self.data["filter_left_time"] @property - @sensor("Filter Life Level", unit="%", icon="mdi:filter-outline") + @sensor("Filter Life Level", unit="%") def filter_life_level(self) -> str: return self.data["filter_life_level"] @property - @sensor("Device Fault", icon="mdi:alert-circle") + @sensor("Device Fault") def device_fault(self) -> FaultStatus | None: try: return FaultStatus(self.data["device_fault"]) @@ -350,7 +350,7 @@ def device_fault(self) -> FaultStatus | None: return None @property - @sensor("Charging State", icon="mdi:battery-charging") + @sensor("Charging State") def charging_state(self) -> ChargingState | None: try: return ChargingState(self.data["charging_state"]) @@ -359,7 +359,7 @@ def charging_state(self) -> ChargingState | None: return None @property - @sensor("Operating Mode", icon="mdi:robot-vacuum") + @sensor("Operating Mode") def operating_mode(self) -> OperatingMode | None: try: return OperatingMode(self.data["operating_mode"]) @@ -368,7 +368,7 @@ def operating_mode(self) -> OperatingMode | None: return None @property - @sensor("Device Status", icon="mdi:robot-vacuum") + @sensor("Device Status") def device_status(self) -> DeviceStatus | None: try: return DeviceStatus(self.data["device_status"]) @@ -377,22 +377,22 @@ def device_status(self) -> DeviceStatus | None: return None @property - @sensor("Timer Enable", icon="mdi:timer") + @sensor("Timer Enable") def timer_enable(self) -> str: return self.data["timer_enable"] @property - @sensor("Start Time", icon="mdi:clock-start") + @sensor("Start Time") def start_time(self) -> str: return self.data["start_time"] @property - @sensor("Stop Time", icon="mdi:clock-end") + @sensor("Stop Time") def stop_time(self) -> str: return self.data["stop_time"] @property - @sensor("Map View", icon="mdi:map") + @sensor("Map View") def map_view(self) -> str: return self.data["map_view"] @@ -404,53 +404,52 @@ def map_view(self) -> str: min_value=0, max_value=100, step=1, - icon="mdi:volume-high", ) def volume(self) -> str: return self.data["volume"] @property - @sensor("Voice Package", icon="mdi:account-voice") + @sensor("Voice Package") def voice_package(self) -> str: return self.data["voice_package"] @property - @sensor("Timezone", icon="mdi:earth") + @sensor("Timezone") def timezone(self) -> str: return self.data["timezone"] @property - @sensor("Cleaning Time", unit="min", icon="mdi:timer-outline") + @sensor("Cleaning Time", unit="min") def cleaning_time(self) -> str: return self.data["cleaning_time"] @property - @sensor("Cleaning Area", unit="m²", icon="mdi:texture-box") + @sensor("Cleaning Area", unit="m²") def cleaning_area(self) -> str: return self.data["cleaning_area"] @property - @sensor("First Clean Time", icon="mdi:clock-outline") + @sensor("First Clean Time") def first_clean_time(self) -> str: return self.data["first_clean_time"] @property - @sensor("Total Clean Time", unit="min", icon="mdi:timer-outline") + @sensor("Total Clean Time", unit="min") def total_clean_time(self) -> str: return self.data["total_clean_time"] @property - @sensor("Total Clean Times", icon="mdi:counter") + @sensor("Total Clean Times") def total_clean_times(self) -> str: return self.data["total_clean_times"] @property - @sensor("Total Clean Area", unit="m²", icon="mdi:texture-box") + @sensor("Total Clean Area", unit="m²") def total_clean_area(self) -> str: return self.data["total_clean_area"] @property - @setting("Cleaning Mode", setter_name="set_fan_speed", icon="mdi:fan") + @setting("Cleaning Mode", setter_name="set_fan_speed") def cleaning_mode(self): cleaning_mode = self.data["cleaning_mode"] cleaning_mode_enum_class = _get_cleaning_mode_enum_class(self.model) @@ -465,25 +464,23 @@ def cleaning_mode(self): return None @property - @sensor("Life Sieve", unit="%", icon="mdi:filter-outline") + @sensor("Life Sieve", unit="%") def life_sieve(self) -> str | None: return self.data.get("life_sieve") @property - @sensor("Life Brush Side", unit="%", icon="mdi:brush") + @sensor("Life Brush Side", unit="%") def life_brush_side(self) -> str | None: return self.data.get("life_brush_side") @property - @sensor("Life Brush Main", unit="%", icon="mdi:brush") + @sensor("Life Brush Main", unit="%") def life_brush_main(self) -> str | None: return self.data.get("life_brush_main") # TODO: get/set water flow for Dreame 1C @property - @setting( - "Water Flow", setter_name="set_waterflow", choices=WaterFlow, icon="mdi:water" - ) + @setting("Water Flow", setter_name="set_waterflow", choices=WaterFlow) def water_flow(self) -> WaterFlow | None: try: water_flow = self.data["water_flow"] @@ -496,7 +493,7 @@ def water_flow(self) -> WaterFlow | None: return None @property - @sensor("Water Box Carriage Attached", icon="mdi:cup-water") + @sensor("Water Box Carriage Attached") def is_water_box_carriage_attached(self) -> bool | None: """Return True if water box carriage (mop) is installed, None if sensor not present.""" diff --git a/miio/integrations/huayi/light/huizuo.py b/miio/integrations/huayi/light/huizuo.py index f599ca32a..4374fa53d 100644 --- a/miio/integrations/huayi/light/huizuo.py +++ b/miio/integrations/huayi/light/huizuo.py @@ -118,7 +118,7 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @sensor("Is On", icon="mdi:power") + @sensor("Is On") def is_on(self) -> bool: """Return True if device is on.""" return self.data["power"] @@ -130,7 +130,6 @@ def is_on(self) -> bool: setter_name="set_brightness", min_value=0, max_value=100, - icon="mdi:brightness-6", ) def brightness(self) -> int: """Return current brightness.""" @@ -143,7 +142,6 @@ def brightness(self) -> int: setter_name="set_color_temp", min_value=3000, max_value=6400, - icon="mdi:thermometer", device_class="temperature", ) def color_temp(self) -> int: @@ -151,7 +149,7 @@ def color_temp(self) -> int: return self.data["color_temp"] @property - @sensor("Fan On", icon="mdi:fan") + @sensor("Fan On") def is_fan_on(self) -> bool | None: """Return True if Fan is on.""" if "fan_power" in self.data: @@ -166,7 +164,7 @@ def fan_speed_level(self) -> int | None: return None @property - @sensor("Fan Reverse", icon="mdi:fan-chevron-down") + @sensor("Fan Reverse") def is_fan_reverse(self) -> bool | None: """Return True if Fan reverse is on.""" if "fan_motor_reverse" in self.data: @@ -174,7 +172,7 @@ def is_fan_reverse(self) -> bool | None: return None @property - @sensor("Fan Mode", icon="mdi:fan-auto") + @sensor("Fan Mode") def fan_mode(self) -> int | None: """Return 0 if 'Basic' and 1 if 'Natural wind'.""" if "fan_mode" in self.data: @@ -182,7 +180,7 @@ def fan_mode(self) -> int | None: return None @property - @sensor("Heater On", icon="mdi:radiator") + @sensor("Heater On") def is_heater_on(self) -> bool | None: """Return True if Heater is on.""" if "heater_power" in self.data: @@ -190,7 +188,7 @@ def is_heater_on(self) -> bool | None: return None @property - @sensor("Heater Fault Code", icon="mdi:alert-circle") + @sensor("Heater Fault Code") def heater_fault_code(self) -> int | None: """Return Heater's fault code. diff --git a/miio/integrations/ksmb/walkingpad/walkingpad.py b/miio/integrations/ksmb/walkingpad/walkingpad.py index 3fec93a4d..9aed4e4be 100644 --- a/miio/integrations/ksmb/walkingpad/walkingpad.py +++ b/miio/integrations/ksmb/walkingpad/walkingpad.py @@ -44,19 +44,19 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @sensor("Power", icon="mdi:power") + @sensor("Power") def power(self) -> str: """Power state.""" return self.data["power"] @property - @sensor("Is On", icon="mdi:power") + @sensor("Is On") def is_on(self) -> bool: """True if the device is turned on.""" return self.power == "on" @property - @sensor("Walking Time", icon="mdi:timer", device_class="duration") + @sensor("Walking Time", device_class="duration") def walking_time(self) -> timedelta: """Current walking duration in seconds.""" return timedelta(seconds=int(self.data["time"])) @@ -68,7 +68,6 @@ def walking_time(self) -> timedelta: setter_name="set_speed", min_value=0, max_value=6, - icon="mdi:speedometer", ) def speed(self) -> float: """Current speed.""" @@ -81,7 +80,6 @@ def speed(self) -> float: setter_name="set_start_speed", min_value=0, max_value=6, - icon="mdi:speedometer-slow", ) def start_speed(self) -> float: """Current start speed.""" @@ -92,7 +90,6 @@ def start_speed(self) -> float: "Mode", setter_name="set_mode", choices=OperationMode, - icon="mdi:run", ) def mode(self) -> OperationMode: """Current mode.""" @@ -103,26 +100,25 @@ def mode(self) -> OperationMode: "Sensitivity", setter_name="set_sensitivity", choices=OperationSensitivity, - icon="mdi:tune", ) def sensitivity(self) -> OperationSensitivity: """Current sensitivity.""" return OperationSensitivity(self.data["sensitivity"]) @property - @sensor("Step Count", icon="mdi:shoe-print") + @sensor("Step Count") def step_count(self) -> int: """Current steps.""" return int(self.data["step"]) @property - @sensor("Distance", unit="m", icon="mdi:map-marker-distance") + @sensor("Distance", unit="m") def distance(self) -> int: """Current distance in meters.""" return int(self.data["dist"]) @property - @sensor("Calories", unit="cal", icon="mdi:fire") + @sensor("Calories", unit="cal") def calories(self) -> int: """Current calories burnt.""" return int(self.data["cal"]) diff --git a/miio/integrations/leshow/fan/fan_leshow.py b/miio/integrations/leshow/fan/fan_leshow.py index 6109959d6..ea0a1f536 100644 --- a/miio/integrations/leshow/fan/fan_leshow.py +++ b/miio/integrations/leshow/fan/fan_leshow.py @@ -46,13 +46,13 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @sensor("Power", icon="mdi:power") + @sensor("Power") def power(self) -> str: """Power state.""" return "on" if self.data["power"] == 1 else "off" @property - @sensor("Is On", icon="mdi:power") + @sensor("Is On") def is_on(self) -> bool: """True if device is turned on.""" return self.data["power"] == 1 @@ -61,7 +61,6 @@ def is_on(self) -> bool: @setting( "Mode", setter_name="set_mode", - icon="mdi:fan", choices=OperationMode, ) def mode(self) -> OperationMode: @@ -72,7 +71,6 @@ def mode(self) -> OperationMode: @setting( "Speed", setter_name="set_speed", - icon="mdi:speedometer", unit="%", min_value=0, max_value=100, @@ -83,13 +81,13 @@ def speed(self) -> int: return self.data["blow"] @property - @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") + @setting("Buzzer", setter_name="set_buzzer") def buzzer(self) -> bool: """True if buzzer is turned on.""" return self.data["sound"] == 1 @property - @setting("Oscillate", setter_name="set_oscillate", icon="mdi:rotate-3d-variant") + @setting("Oscillate", setter_name="set_oscillate") def oscillate(self) -> bool: """True if oscillation is enabled.""" return self.data["yaw"] == 1 @@ -98,7 +96,6 @@ def oscillate(self) -> bool: @setting( "Delay Off Countdown", setter_name="delay_off", - icon="mdi:timer", device_class="duration", unit="min", min_value=0, @@ -110,7 +107,7 @@ def delay_off_countdown(self) -> int: return self.data["timer"] @property - @sensor("Error Detected", icon="mdi:alert-circle") + @sensor("Error Detected") def error_detected(self) -> bool: """True if a fault was detected.""" return self.data["fault"] == 1 diff --git a/miio/integrations/lumi/acpartner/airconditioningcompanion.py b/miio/integrations/lumi/acpartner/airconditioningcompanion.py index 50cab2694..0147a0adf 100644 --- a/miio/integrations/lumi/acpartner/airconditioningcompanion.py +++ b/miio/integrations/lumi/acpartner/airconditioningcompanion.py @@ -98,13 +98,13 @@ def __init__(self, data): self.state = data["model_and_state"][1] @property - @sensor("Load Power", unit="W", device_class="power", icon="mdi:flash") + @sensor("Load Power", unit="W", device_class="power") def load_power(self) -> int: """Current power load of the air conditioner.""" return int(self.data["model_and_state"][2]) @property - @sensor("Power Socket", icon="mdi:power-socket") + @sensor("Power Socket") def power_socket(self) -> str | None: """Current socket power state.""" if "power_socket" in self.data and self.data["power_socket"] is not None: @@ -113,25 +113,25 @@ def power_socket(self) -> str | None: return None @property - @sensor("Air Condition Model", icon="mdi:air-conditioner") + @sensor("Air Condition Model") def air_condition_model(self) -> bytes: """Model of the air conditioner.""" return bytes.fromhex(self.model) @property - @sensor("Model Format", icon="mdi:information-outline") + @sensor("Model Format") def model_format(self) -> int: """Version number of the model format.""" return self.air_condition_model[0] @property - @sensor("Device Type", icon="mdi:devices") + @sensor("Device Type") def device_type(self) -> int: """Device type identifier.""" return self.air_condition_model[1] @property - @sensor("Air Condition Brand", icon="mdi:tag") + @sensor("Air Condition Brand") def air_condition_brand(self) -> int: """Brand of the air conditioner. @@ -140,7 +140,7 @@ def air_condition_brand(self) -> int: return int(self.air_condition_model[2:4].hex(), 16) @property - @sensor("Air Condition Remote", icon="mdi:remote") + @sensor("Air Condition Remote") def air_condition_remote(self) -> int: """Remote id. @@ -156,7 +156,7 @@ def air_condition_remote(self) -> int: return int(self.air_condition_model[4:8].hex(), 16) @property - @sensor("State Format", icon="mdi:information-outline") + @sensor("State Format") def state_format(self) -> int: """Version number of the state format. @@ -165,18 +165,18 @@ def state_format(self) -> int: return int(self.air_condition_model[8]) @property - @sensor("Air Condition Configuration", icon="mdi:cog") + @sensor("Air Condition Configuration") def air_condition_configuration(self) -> int: return self.state[2:10] @property - @sensor("Power", icon="mdi:power") + @sensor("Power") def power(self) -> str: """Current power state.""" return "on" if int(self.state[2:3]) == Power.On.value else "off" @property - @sensor("LED", icon="mdi:led-on") + @sensor("LED") def led(self) -> bool | None: """Current LED state.""" state = self.state[8:9] @@ -190,18 +190,13 @@ def led(self) -> bool | None: return None @property - @sensor("Is On", icon="mdi:power") + @sensor("Is On") def is_on(self) -> bool: """True if the device is turned on.""" return self.power == "on" @property - @sensor( - "Target Temperature", - unit="°C", - device_class="temperature", - icon="mdi:thermometer", - ) + @sensor("Target Temperature", unit="°C", device_class="temperature") def target_temperature(self) -> int | None: """Target temperature.""" try: @@ -210,7 +205,7 @@ def target_temperature(self) -> int | None: return None @property - @sensor("Swing Mode", icon="mdi:arrow-oscillating") + @sensor("Swing Mode") def swing_mode(self) -> SwingMode | None: """Current swing mode.""" try: @@ -220,7 +215,7 @@ def swing_mode(self) -> SwingMode | None: return None @property - @sensor("Fan Speed", icon="mdi:fan") + @sensor("Fan Speed") def fan_speed(self) -> FanSpeed | None: """Current fan speed.""" try: @@ -230,7 +225,7 @@ def fan_speed(self) -> FanSpeed | None: return None @property - @sensor("Mode", icon="mdi:air-conditioner") + @sensor("Mode") def mode(self) -> OperationMode | None: """Current operation mode.""" try: diff --git a/miio/integrations/lumi/acpartner/airconditioningcompanionMCN.py b/miio/integrations/lumi/acpartner/airconditioningcompanionMCN.py index 72c54268c..e815fee5c 100644 --- a/miio/integrations/lumi/acpartner/airconditioningcompanionMCN.py +++ b/miio/integrations/lumi/acpartner/airconditioningcompanionMCN.py @@ -45,30 +45,25 @@ def __init__(self, data): self.data = data @property - @sensor("Load Power", unit="W", icon="mdi:flash", device_class="power") + @sensor("Load Power", unit="W", device_class="power") def load_power(self) -> int: """Current power load of the air conditioner.""" return int(self.data[-1]) @property - @sensor("Power", icon="mdi:power") + @sensor("Power") def power(self) -> str: """Current power state.""" return self.data[0] @property - @setting("Power", setter_name="on", icon="mdi:power") + @setting("Power", setter_name="on") def is_on(self) -> bool: """True if the device is turned on.""" return self.power == "on" @property - @setting( - "Mode", - setter_name="send_command", - icon="mdi:air-conditioner", - choices=OperationMode, - ) + @setting("Mode", setter_name="send_command", choices=OperationMode) def mode(self) -> OperationMode | None: """Current operation mode.""" try: @@ -82,7 +77,6 @@ def mode(self) -> OperationMode | None: "Target Temperature", setter_name="send_command", unit="°C", - icon="mdi:thermometer", device_class="temperature", ) def target_temperature(self) -> int | None: @@ -93,7 +87,7 @@ def target_temperature(self) -> int | None: return None @property - @setting("Fan Speed", setter_name="send_command", icon="mdi:fan", choices=FanSpeed) + @setting("Fan Speed", setter_name="send_command", choices=FanSpeed) def fan_speed(self) -> FanSpeed | None: """Current fan speed.""" try: @@ -103,12 +97,7 @@ def fan_speed(self) -> FanSpeed | None: return None @property - @setting( - "Swing Mode", - setter_name="send_command", - icon="mdi:arrow-oscillating", - choices=SwingMode, - ) + @setting("Swing Mode", setter_name="send_command", choices=SwingMode) def swing_mode(self) -> SwingMode | None: """Current swing mode.""" try: diff --git a/miio/integrations/lumi/camera/aqaracamera.py b/miio/integrations/lumi/camera/aqaracamera.py index e9d4ccdc8..120bb7b00 100644 --- a/miio/integrations/lumi/camera/aqaracamera.py +++ b/miio/integrations/lumi/camera/aqaracamera.py @@ -76,25 +76,25 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @sensor("Type", icon="mdi:camera") + @sensor("Type") def type(self) -> str: """TODO: Type of the camera? Name?""" return self.data["app_type"] @property - @sensor("Video Status", icon="mdi:video") + @sensor("Video Status") def video_status(self) -> bool: """Video state.""" return bool(self.data["video_state"]) @property - @sensor("Is On", icon="mdi:video") + @sensor("Is On") def is_on(self) -> bool: """True if device is currently on.""" return self.video_status == 1 @property - @setting("Motion Detection", setter_name="md_on", icon="mdi:motion-sensor") + @setting("Motion Detection", setter_name="md_on") def md(self) -> bool: """Motion detection state.""" return bool(self.data["md_status"]) @@ -103,32 +103,31 @@ def md(self) -> bool: @setting( "Motion Detection Sensitivity", setter_name="md_sensitivity", - icon="mdi:motion-sensor", ) def md_sensitivity(self): """Motion detection sensitivity.""" return self.data["mdsensitivity"] @property - @setting("IR Mode", setter_name="ir_on", icon="mdi:remote") + @setting("IR Mode", setter_name="ir_on") def ir(self): """IR mode.""" return bool(self.data["ir_status"]) @property - @setting("LED", setter_name="led_on", icon="mdi:led-on") + @setting("LED", setter_name="led_on") def led(self): """LED status.""" return bool(self.data["led_status"]) @property - @setting("Flipped", setter_name="flip_on", icon="mdi:flip-vertical") + @setting("Flipped", setter_name="flip_on") def flipped(self) -> bool: """TODO: If camera is flipped?""" return self.data["flip_state"] @property - @sensor("Camera Offsets", icon="mdi:camera-control") + @sensor("Camera Offsets") def offsets(self) -> CameraOffset: """Camera offset information.""" return CameraOffset( @@ -138,31 +137,31 @@ def offsets(self) -> CameraOffset: ) @property - @sensor("Channel ID", icon="mdi:access-point-network") + @sensor("Channel ID") def channel_id(self) -> int: """TODO: Zigbee channel?""" return self.data["channel_id"] @property - @setting("Fullstop", setter_name="fullstop_on", icon="mdi:alarm-light") + @setting("Fullstop", setter_name="fullstop_on") def fullstop(self) -> bool: """Is alarm triggered by MD.""" return self.data["fullstop"] != 0 @property - @sensor("P2P ID", icon="mdi:identifier") + @sensor("P2P ID") def p2p_id(self) -> str: """P2P ID for video and audio.""" return self.data["p2p_id"] @property - @sensor("AV ID", icon="mdi:identifier") + @sensor("AV ID") def av_id(self) -> str: """TODO: What is this? ID for the cloud?""" return self.data["avID"] @property - @sensor("AV Password", icon="mdi:lock") + @sensor("AV Password") def av_password(self) -> str: """TODO: What is this? Password for the cloud?""" return self.data["avPass"] diff --git a/miio/integrations/lumi/curtain/curtain_youpin.py b/miio/integrations/lumi/curtain/curtain_youpin.py index cb85fc9d6..49af25e83 100644 --- a/miio/integrations/lumi/curtain/curtain_youpin.py +++ b/miio/integrations/lumi/curtain/curtain_youpin.py @@ -74,15 +74,13 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @sensor("Status", icon="mdi:curtains") + @sensor("Status") def status(self) -> Status: """Device status.""" return Status(self.data["status"]) @property - @setting( - "Manual Enabled", setter_name="set_manual_enabled", icon="mdi:hand-back-left" - ) + @setting("Manual Enabled", setter_name="set_manual_enabled") def is_manual_enabled(self) -> bool: """True if manual controls are enabled.""" return bool(self.data["is_manual_enabled"]) @@ -91,7 +89,6 @@ def is_manual_enabled(self) -> bool: @setting( "Polarity", setter_name="set_polarity", - icon="mdi:swap-horizontal", choices=Polarity, ) def polarity(self) -> Polarity: @@ -102,28 +99,25 @@ def polarity(self) -> Polarity: @setting( "Position Limited", setter_name="set_position_limit", - icon="mdi:arrow-collapse-horizontal", ) def is_position_limited(self) -> bool: """Position limit.""" return bool(self.data["is_position_limited"]) @property - @setting( - "Night Tip Light", setter_name="set_night_tip_light", icon="mdi:lightbulb-night" - ) + @setting("Night Tip Light", setter_name="set_night_tip_light") def night_tip_light(self) -> bool: """Night tip light status.""" return bool(self.data["night_tip_light"]) @property - @sensor("Run Time", icon="mdi:timer-outline", device_class="duration", unit="s") + @sensor("Run Time", device_class="duration", unit="s") def run_time(self) -> int: """Run time of the motor.""" return self.data["run_time"] @property - @sensor("Current Position", icon="mdi:curtains", unit="%") + @sensor("Current Position", unit="%") def current_position(self) -> int: """Current curtain position.""" return self.data["current_position"] @@ -132,7 +126,6 @@ def current_position(self) -> int: @setting( "Target Position", setter_name="set_target_position", - icon="mdi:curtains", unit="%", min_value=0, max_value=100, @@ -146,7 +139,6 @@ def target_position(self) -> int: @setting( "Adjust Value", setter_name="set_adjust_value", - icon="mdi:tune", min_value=-100, max_value=100, step=1, diff --git a/miio/integrations/mijia/vacuum/g1vacuum.py b/miio/integrations/mijia/vacuum/g1vacuum.py index a2088c683..60a0227ee 100644 --- a/miio/integrations/mijia/vacuum/g1vacuum.py +++ b/miio/integrations/mijia/vacuum/g1vacuum.py @@ -160,25 +160,25 @@ def __init__(self, data): self.data = data @property - @sensor("Battery", unit="%", device_class="battery", icon="mdi:battery") + @sensor("Battery", unit="%", device_class="battery") def battery(self) -> int: """Battery Level.""" return self.data["battery"] @property - @sensor("Charge State", icon="mdi:battery-charging") + @sensor("Charge State") def charge_state(self) -> G1ChargeState: """Charging State.""" return G1ChargeState(self.data["charge_state"]) @property - @sensor("Error Code", icon="mdi:alert-circle") + @sensor("Error Code") def error_code(self) -> int: """Error code as returned by the device.""" return int(self.data["error_code"]) @property - @sensor("Error", icon="mdi:alert-circle") + @sensor("Error") def error(self) -> str: """Human readable error description, see also :func:`error_code`.""" try: @@ -187,81 +187,80 @@ def error(self) -> str: return f"Definition missing for error {self.error_code}" @property - @sensor("State", icon="mdi:robot-vacuum") + @property + @sensor("State") def state(self) -> G1State: """Vacuum Status.""" return G1State(self.data["state"]) @property - @setting( - "Fan Speed", setter_name="set_fan_speed", choices=G1FanSpeed, icon="mdi:fan" - ) + @setting("Fan Speed", setter_name="set_fan_speed", choices=G1FanSpeed) def fan_speed(self) -> G1FanSpeed: """Fan Speed.""" return G1FanSpeed(self.data["fan_speed"]) @property - @sensor("Operating Mode", icon="mdi:robot-vacuum") + @sensor("Operating Mode") def operating_mode(self) -> G1VacuumMode: """Operating Mode.""" return G1VacuumMode(self.data["operating_mode"]) @property - @sensor("Mop State", icon="mdi:robot-vacuum-variant") + @sensor("Mop State") def mop_state(self) -> G1MopState: """Mop State.""" return G1MopState(self.data["mop_state"]) @property - @sensor("Water Level", icon="mdi:water") + @sensor("Water Level") def water_level(self) -> G1WaterLevel: """Water Level.""" return G1WaterLevel(self.data["water_level"]) @property - @sensor("Main Brush Life Level", unit="%", icon="mdi:brush") + @sensor("Main Brush Life Level", unit="%") def main_brush_life_level(self) -> int: """Main Brush Life Level in %.""" return self.data["main_brush_life_level"] @property - @sensor("Main Brush Time Left", icon="mdi:brush") + @sensor("Main Brush Time Left") def main_brush_time_left(self) -> timedelta: """Main Brush Remaining Time in Minutes.""" return timedelta(minutes=self.data["main_brush_time_left"]) @property - @sensor("Side Brush Life Level", unit="%", icon="mdi:brush") + @sensor("Side Brush Life Level", unit="%") def side_brush_life_level(self) -> int: """Side Brush Life Level in %.""" return self.data["side_brush_life_level"] @property - @sensor("Side Brush Time Left", icon="mdi:brush") + @sensor("Side Brush Time Left") def side_brush_time_left(self) -> timedelta: """Side Brush Remaining Time in Minutes.""" return timedelta(minutes=self.data["side_brush_time_left"]) @property - @sensor("Filter Life Level", unit="%", icon="mdi:filter-outline") + @sensor("Filter Life Level", unit="%") def filter_life_level(self) -> int: """Filter Life Level in %.""" return self.data["filter_life_level"] @property - @sensor("Filter Time Left", icon="mdi:filter-outline") + @sensor("Filter Time Left") def filter_time_left(self) -> timedelta: """Filter remaining time.""" return timedelta(minutes=self.data["filter_time_left"]) @property - @sensor("Clean Area", unit="cm²", icon="mdi:texture-box") + @sensor("Clean Area", unit="cm²") def clean_area(self) -> int: """Clean Area in cm2.""" return self.data["clean_area"] @property - @sensor("Clean Time", icon="mdi:timer-outline") + @sensor("Clean Time") def clean_time(self) -> timedelta: """Clean time.""" return timedelta(minutes=self.data["clean_time"]) @@ -283,19 +282,19 @@ def __init__(self, data) -> None: self.data = data @property - @sensor("Total Clean Count", icon="mdi:counter") + @sensor("Total Clean Count") def total_clean_count(self) -> int: """Total Number of Cleanings.""" return self.data["total_clean_count"] @property - @sensor("Total Clean Area", unit="m²", icon="mdi:texture-box") + @sensor("Total Clean Area", unit="m²") def total_clean_area(self) -> int: """Total Area Cleaned in m2.""" return self.data["total_clean_area"] @property - @sensor("Total Clean Time", icon="mdi:timer-outline") + @sensor("Total Clean Time") def total_clean_time(self) -> timedelta: """Total Cleaning Time.""" return timedelta(hours=self.data["total_clean_area"]) diff --git a/miio/integrations/mmgg/petwaterdispenser/status.py b/miio/integrations/mmgg/petwaterdispenser/status.py index 29c092b9f..78cd44fde 100644 --- a/miio/integrations/mmgg/petwaterdispenser/status.py +++ b/miio/integrations/mmgg/petwaterdispenser/status.py @@ -35,13 +35,13 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @sensor(name="Sponge Filter Left Days", icon="mdi:filter") + @sensor(name="Sponge Filter Left Days") def sponge_filter_left_days(self) -> timedelta: """Filter life time remaining in days.""" return timedelta(days=self.data["filter_left_time"]) @property - @setting(name="Power", setter_name="on", icon="mdi:power") + @setting(name="Power", setter_name="on") def is_on(self) -> bool: """True if device is on.""" return self.data["on"] @@ -50,7 +50,6 @@ def is_on(self) -> bool: @setting( name="Mode", setter_name="set_mode", - icon="mdi:water-pump", choices=OperatingMode, ) def mode(self) -> OperatingMode: @@ -58,25 +57,25 @@ def mode(self) -> OperatingMode: return OperatingMode(self.data["mode"]) @property - @setting(name="LED", setter_name="set_led", icon="mdi:led-outline") + @setting(name="LED", setter_name="set_led") def is_led_on(self) -> bool: """True if enabled.""" return self.data["indicator_light"] @property - @sensor(name="Cotton Left Days", icon="mdi:filter") + @sensor(name="Cotton Left Days") def cotton_left_days(self) -> timedelta: """Cotton filter life time remaining in days.""" return timedelta(days=self.data["cotton_left_time"]) @property - @sensor(name="Before Cleaning Days", icon="mdi:broom") + @sensor(name="Before Cleaning Days") def before_cleaning_days(self) -> timedelta: """Days before cleaning.""" return timedelta(days=self.data["remain_clean_time"]) @property - @sensor(name="No Water", icon="mdi:water-off") + @sensor(name="No Water") def is_no_water(self) -> bool: """True if there is no water left.""" if self.data["no_water_flag"]: @@ -84,19 +83,19 @@ def is_no_water(self) -> bool: return True @property - @sensor(name="No Water Duration", icon="mdi:water-off") + @sensor(name="No Water Duration") def no_water_minutes(self) -> timedelta: """Minutes without water.""" return timedelta(minutes=self.data["no_water_time"]) @property - @sensor(name="Pump Blocked", icon="mdi:water-pump-off") + @sensor(name="Pump Blocked") def is_pump_blocked(self) -> bool: """True if pump is blocked.""" return self.data["pump_block_flag"] @property - @sensor(name="Lid Up", icon="mdi:archive-arrow-up") + @sensor(name="Lid Up") def is_lid_up(self) -> bool: """True if lid is up.""" return self.data["lid_up_flag"] @@ -105,7 +104,6 @@ def is_lid_up(self) -> bool: @setting( name="Timezone", setter_name="set_timezone", - icon="mdi:map-clock", min_value=-12, max_value=12, ) @@ -114,13 +112,13 @@ def timezone(self) -> int: return self.data["timezone"] @property - @setting(name="Location", setter_name="set_location", icon="mdi:map-marker") + @setting(name="Location", setter_name="set_location") def location(self) -> str: """Device location string.""" return self.data["location"] @property - @sensor(name="Error Detected", icon="mdi:alert-circle") + @sensor(name="Error Detected") def is_error_detected(self) -> bool: """True if fault detected.""" return self.data["fault"] > 0 diff --git a/miio/integrations/nwt/dehumidifier/airdehumidifier.py b/miio/integrations/nwt/dehumidifier/airdehumidifier.py index 167d3b37a..132e150ce 100644 --- a/miio/integrations/nwt/dehumidifier/airdehumidifier.py +++ b/miio/integrations/nwt/dehumidifier/airdehumidifier.py @@ -64,13 +64,13 @@ def __init__(self, data: dict[str, Any], device_info: DeviceInfo) -> None: self.device_info = device_info @property - @sensor("Power", icon="mdi:power") + @sensor("Power") def power(self) -> str: """Power state.""" return self.data["on_off"] @property - @sensor("Is On", icon="mdi:power") + @sensor("Is On") def is_on(self) -> bool: """True if device is turned on.""" return self.power == "on" @@ -80,7 +80,6 @@ def is_on(self) -> bool: "Mode", setter_name="set_mode", choices=OperationMode, - icon="mdi:air-humidifier", ) def mode(self) -> OperationMode: """Operation mode. @@ -90,9 +89,7 @@ def mode(self) -> OperationMode: return OperationMode(self.data["mode"]) @property - @sensor( - "Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer" - ) + @sensor("Temperature", unit="°C", device_class="temperature") def temperature(self) -> float | None: """Current temperature, if available.""" if "temp" in self.data and self.data["temp"] is not None: @@ -100,25 +97,25 @@ def temperature(self) -> float | None: return None @property - @sensor("Humidity", unit="%", device_class="humidity", icon="mdi:water-percent") + @sensor("Humidity", unit="%", device_class="humidity") def humidity(self) -> int: """Current humidity.""" return self.data["humidity"] @property - @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") + @setting("Buzzer", setter_name="set_buzzer") def buzzer(self) -> bool: """True if buzzer is turned on.""" return self.data["buzzer"] == "on" @property - @setting("LED", setter_name="set_led", icon="mdi:led-on") + @setting("LED", setter_name="set_led") def led(self) -> bool: """LED brightness if available.""" return self.data["led"] == "on" @property - @setting("Child Lock", setter_name="set_child_lock", icon="mdi:lock") + @setting("Child Lock", setter_name="set_child_lock") def child_lock(self) -> bool: """Return True if child lock is on.""" return self.data["child_lock"] == "on" @@ -141,31 +138,31 @@ def fan_speed(self) -> FanSpeed | None: return None @property - @sensor("Tank Full", icon="mdi:cup-water") + @sensor("Tank Full") def tank_full(self) -> bool: """The remaining amount of water in percent.""" return self.data["tank_full"] == "on" @property - @sensor("Compressor Status", icon="mdi:air-conditioner") + @sensor("Compressor Status") def compressor_status(self) -> bool: """Compressor status.""" return self.data["compressor_status"] == "on" @property - @sensor("Defrost Status", icon="mdi:snowflake-melt") + @sensor("Defrost Status") def defrost_status(self) -> bool: """Defrost status.""" return self.data["defrost_status"] == "on" @property - @sensor("Fan St", icon="mdi:fan") + @sensor("Fan St") def fan_st(self) -> int: """Fan st.""" return self.data["fan_st"] @property - @sensor("Alarm", icon="mdi:alarm-light") + @sensor("Alarm") def alarm(self) -> str: """Alarm.""" return self.data["alarm"] diff --git a/miio/integrations/philips/light/ceil.py b/miio/integrations/philips/light/ceil.py index 032ad42a5..46fda9abf 100644 --- a/miio/integrations/philips/light/ceil.py +++ b/miio/integrations/philips/light/ceil.py @@ -26,13 +26,13 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @sensor("Power", icon="mdi:power") + @sensor("Power") def power(self) -> str: """Power state.""" return self.data["power"] @property - @sensor("Is On", icon="mdi:power") + @sensor("Is On") def is_on(self) -> bool: """True if the device is turned on.""" return self.power == "on" @@ -41,7 +41,6 @@ def is_on(self) -> bool: @setting( "Brightness", setter_name="set_brightness", - icon="mdi:brightness-6", unit="%", min_value=1, max_value=100, @@ -55,7 +54,6 @@ def brightness(self) -> int: @setting( "Scene", setter_name="set_scene", - icon="mdi:palette", min_value=1, max_value=4, step=1, @@ -68,7 +66,6 @@ def scene(self) -> int: @setting( "Delay Off Countdown", setter_name="delay_off", - icon="mdi:timer", device_class="duration", unit="s", ) @@ -80,7 +77,6 @@ def delay_off_countdown(self) -> int: @setting( "Color Temperature", setter_name="set_color_temperature", - icon="mdi:temperature-kelvin", min_value=1, max_value=100, step=1, @@ -90,13 +86,13 @@ def color_temperature(self) -> int: return self.data["cct"] @property - @sensor("Smart Night Light", icon="mdi:weather-night") + @sensor("Smart Night Light") def smart_night_light(self) -> bool: """Smart night mode state.""" return self.data["bl"] == 1 @property - @sensor("Automatic Color Temperature", icon="mdi:theme-light-dark") + @sensor("Automatic Color Temperature") def automatic_color_temperature(self) -> bool: """Automatic color temperature state.""" return self.data["ac"] == 1 diff --git a/miio/integrations/philips/light/philips_bulb.py b/miio/integrations/philips/light/philips_bulb.py index 18e707b8b..c7658e108 100644 --- a/miio/integrations/philips/light/philips_bulb.py +++ b/miio/integrations/philips/light/philips_bulb.py @@ -38,19 +38,17 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @sensor("Power", icon="mdi:power") + @sensor("Power") def power(self) -> str: return self.data["power"] @property - @setting("Power", setter_name="on", icon="mdi:power") + @setting("Power", setter_name="on") def is_on(self) -> bool: return self.power == "on" @property - @setting( - "Brightness", setter_name="set_brightness", unit="%", icon="mdi:brightness-6" - ) + @setting("Brightness", setter_name="set_brightness", unit="%") def brightness(self) -> int | None: if "bright" in self.data: return self.data["bright"] @@ -59,16 +57,14 @@ def brightness(self) -> int | None: return None @property - @setting( - "Color Temperature", setter_name="set_color_temperature", icon="mdi:palette" - ) + @setting("Color Temperature", setter_name="set_color_temperature") def color_temperature(self) -> int | None: if "cct" in self.data: return self.data["cct"] return None @property - @setting("Scene", setter_name="set_scene", icon="mdi:palette") + @setting("Scene", setter_name="set_scene") def scene(self) -> int | None: if "snm" in self.data: return self.data["snm"] @@ -78,7 +74,6 @@ def scene(self) -> int | None: @sensor( "Delay Off Countdown", unit="s", - icon="mdi:timer-outline", device_class="duration", ) def delay_off_countdown(self) -> int: diff --git a/miio/integrations/philips/light/philips_eyecare.py b/miio/integrations/philips/light/philips_eyecare.py index 68fb1a226..33d066393 100644 --- a/miio/integrations/philips/light/philips_eyecare.py +++ b/miio/integrations/philips/light/philips_eyecare.py @@ -21,13 +21,13 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @sensor("Power", icon="mdi:power") + @sensor("Power") def power(self) -> str: """Power state.""" return self.data["power"] @property - @sensor("Is On", icon="mdi:power") + @sensor("Is On") def is_on(self) -> bool: """True if the device is turned on.""" return self.power == "on" @@ -39,20 +39,19 @@ def is_on(self) -> bool: setter_name="set_brightness", min_value=1, max_value=100, - icon="mdi:brightness-6", ) def brightness(self) -> int: """Current brightness of the primary light.""" return self.data["bright"] @property - @setting("Eye Fatigue Reminder", setter_name="reminder_on", icon="mdi:eye") + @setting("Eye Fatigue Reminder", setter_name="reminder_on") def reminder(self) -> bool: """Indicates the eye fatigue notification is enabled or not.""" return self.data["notifystatus"] == "on" @property - @setting("Ambient Light", setter_name="ambient_on", icon="mdi:lightbulb-outline") + @setting("Ambient Light", setter_name="ambient_on") def ambient(self) -> bool: """True if the ambient light (second light source) is on.""" return self.data["ambstatus"] == "on" @@ -64,14 +63,13 @@ def ambient(self) -> bool: setter_name="set_ambient_brightness", min_value=1, max_value=100, - icon="mdi:brightness-6", ) def ambient_brightness(self) -> int: """Brightness of the ambient light.""" return self.data["ambvalue"] @property - @setting("Eyecare Mode", setter_name="eyecare_on", icon="mdi:eye-check") + @setting("Eyecare Mode", setter_name="eyecare_on") def eyecare(self) -> bool: """True if the eyecare mode is on.""" return self.data["eyecare"] == "on" @@ -82,7 +80,6 @@ def eyecare(self) -> bool: setter_name="set_scene", min_value=1, max_value=4, - icon="mdi:palette", ) def scene(self) -> int: """Current fixed scene.""" @@ -92,7 +89,6 @@ def scene(self) -> int: @setting( "Smart Night Light", setter_name="smart_night_light_on", - icon="mdi:weather-night", ) def smart_night_light(self) -> bool: """True if the smart night light mode is on.""" @@ -102,7 +98,6 @@ def smart_night_light(self) -> bool: @sensor( "Delay Off Countdown", unit="min", - icon="mdi:timer-sand", device_class="duration", ) def delay_off_countdown(self) -> int: diff --git a/miio/integrations/philips/light/philips_moonlight.py b/miio/integrations/philips/light/philips_moonlight.py index 8163a0e6e..8005a4346 100644 --- a/miio/integrations/philips/light/philips_moonlight.py +++ b/miio/integrations/philips/light/philips_moonlight.py @@ -24,12 +24,12 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @sensor(name="Power", icon="mdi:power") + @sensor(name="Power") def power(self) -> str: return self.data["pow"] @property - @setting(name="Power", setter_name="on", icon="mdi:power") + @setting(name="Power", setter_name="on") def is_on(self) -> bool: return self.power == "on" @@ -38,7 +38,6 @@ def is_on(self) -> bool: name="Brightness", setter_name="set_brightness", unit="%", - icon="mdi:brightness-6", min_value=1, max_value=100, ) @@ -49,7 +48,6 @@ def brightness(self) -> int: @setting( name="Color Temperature", setter_name="set_color_temperature", - icon="mdi:thermometer", min_value=1, max_value=100, ) @@ -57,7 +55,7 @@ def color_temperature(self) -> int: return self.data["cct"] @property - @setting(name="RGB", setter_name="set_rgb", icon="mdi:palette") + @setting(name="RGB", setter_name="set_rgb") def rgb(self) -> tuple[int, int, int]: """Return color in RGB.""" return int_to_rgb(int(self.data["rgb"])) @@ -66,7 +64,6 @@ def rgb(self) -> tuple[int, int, int]: @setting( name="Scene", setter_name="set_scene", - icon="mdi:palette-swatch", min_value=1, max_value=6, ) @@ -74,7 +71,7 @@ def scene(self) -> int: return self.data["snm"] @property - @sensor(name="Sleep Assistant", icon="mdi:sleep") + @sensor(name="Sleep Assistant") def sleep_assistant(self) -> int: """Example values: @@ -86,29 +83,29 @@ def sleep_assistant(self) -> int: return self.data["sta"] @property - @sensor(name="Sleep Off Time", unit="s", icon="mdi:timer-off") + @sensor(name="Sleep Off Time", unit="s") def sleep_off_time(self) -> int: return self.data["spr"] @property - @sensor(name="Total Assistant Sleep Time", unit="s", icon="mdi:timer") + @sensor(name="Total Assistant Sleep Time", unit="s") def total_assistant_sleep_time(self) -> int: return self.data["spt"] @property - @sensor(name="Brand Sleep", icon="mdi:sleep") + @sensor(name="Brand Sleep") def brand_sleep(self) -> bool: # sp_sleep_open? return self.data["ms"] == 1 @property - @sensor(name="Brand", icon="mdi:watch") + @sensor(name="Brand") def brand(self) -> bool: # sp_xm_bracelet? return self.data["mb"] == 1 @property - @sensor(name="Wake Up Time", icon="mdi:alarm") + @sensor(name="Wake Up Time") def wake_up_time(self) -> list[int]: # Example: [weekdays?, hour, minute] return self.data["wkp"] diff --git a/miio/integrations/philips/light/philips_rwread.py b/miio/integrations/philips/light/philips_rwread.py index ade2f17b5..6df10bddb 100644 --- a/miio/integrations/philips/light/philips_rwread.py +++ b/miio/integrations/philips/light/philips_rwread.py @@ -36,13 +36,13 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @sensor("Power", icon="mdi:power") + @sensor("Power") def power(self) -> str: """Power state.""" return self.data["power"] @property - @sensor("Is On", icon="mdi:power") + @sensor("Is On") def is_on(self) -> bool: """True if the device is turned on.""" return self.power == "on" @@ -51,7 +51,6 @@ def is_on(self) -> bool: @setting( "Brightness", setter_name="set_brightness", - icon="mdi:brightness-6", unit="%", min_value=1, max_value=100, @@ -65,7 +64,6 @@ def brightness(self) -> int: @setting( "Delay Off Countdown", setter_name="delay_off", - icon="mdi:timer", device_class="duration", unit="s", ) @@ -77,7 +75,6 @@ def delay_off_countdown(self) -> int: @setting( "Scene", setter_name="set_scene", - icon="mdi:palette", min_value=1, max_value=4, step=1, @@ -87,9 +84,7 @@ def scene(self) -> int: return self.data["snm"] @property - @setting( - "Motion Detection", setter_name="set_motion_detection", icon="mdi:motion-sensor" - ) + @setting("Motion Detection", setter_name="set_motion_detection") def motion_detection(self) -> bool: """True if motion detection is enabled.""" return self.data["flm"] == 1 @@ -98,7 +93,6 @@ def motion_detection(self) -> bool: @setting( "Motion Detection Sensitivity", setter_name="set_motion_detection_sensitivity", - icon="mdi:signal-cellular-2", choices=MotionDetectionSensitivity, ) def motion_detection_sensitivity(self) -> MotionDetectionSensitivity: @@ -106,7 +100,7 @@ def motion_detection_sensitivity(self) -> MotionDetectionSensitivity: return MotionDetectionSensitivity(self.data["flmv"]) @property - @setting("Child Lock", setter_name="set_child_lock", icon="mdi:lock") + @setting("Child Lock", setter_name="set_child_lock") def child_lock(self) -> bool: """True if child lock is enabled.""" return self.data["chl"] == 1 diff --git a/miio/integrations/pwzn/relay/pwzn_relay.py b/miio/integrations/pwzn/relay/pwzn_relay.py index 1f93b1d7a..3855705f7 100644 --- a/miio/integrations/pwzn/relay/pwzn_relay.py +++ b/miio/integrations/pwzn/relay/pwzn_relay.py @@ -71,7 +71,7 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @sensor("Relay State", icon="mdi:electric-switch") + @sensor("Relay State") def relay_state(self) -> int | None: """Current relay state.""" if "relay_status" in self.data: @@ -79,7 +79,7 @@ def relay_state(self) -> int | None: return None @property - @sensor("Relay Names", icon="mdi:rename-box") + @sensor("Relay Names") def relay_names(self) -> dict[int, str]: def _extract_index_from_key(name) -> int: """extract the index from the variable.""" @@ -92,7 +92,7 @@ def _extract_index_from_key(name) -> int: } @property - @sensor("Active Relay Count", icon="mdi:counter") + @sensor("Active Relay Count") def on_count(self) -> int | None: """Number of on relay.""" if "on_count" in self.data: diff --git a/miio/integrations/roidmi/vacuum/roidmivacuum_miot.py b/miio/integrations/roidmi/vacuum/roidmivacuum_miot.py index 5312d84fb..1127b5867 100644 --- a/miio/integrations/roidmi/vacuum/roidmivacuum_miot.py +++ b/miio/integrations/roidmi/vacuum/roidmivacuum_miot.py @@ -225,19 +225,19 @@ def __init__(self, data): self.data = data @property - @sensor("Battery", unit="%", device_class="battery", icon="mdi:battery") + @sensor("Battery", unit="%", device_class="battery") def battery(self) -> int: """Remaining battery in percentage.""" return self.data["battery_level"] @property - @sensor("Error Code", icon="mdi:alert-circle") + @sensor("Error Code") def error_code(self) -> int: """Error code as returned by the device.""" return int(self.data["error_code"]) @property - @sensor("Error", icon="mdi:alert-circle") + @sensor("Error") def error(self) -> str: """Human readable error description, see also :func:`error_code`.""" try: @@ -246,7 +246,8 @@ def error(self) -> str: return f"Definition missing for error {self.error_code}" @property - @sensor("Charging State", icon="mdi:battery-charging") + @property + @sensor("Charging State") def charging_state(self) -> ChargingState: """Charging state (Charging/Discharging)""" try: @@ -256,7 +257,7 @@ def charging_state(self) -> ChargingState: return ChargingState.Unknown @property - @sensor("Sweep Mode", icon="mdi:robot-vacuum") + @sensor("Sweep Mode") def sweep_mode(self) -> SweepMode: """Sweep mode point/area/total etc.""" try: @@ -266,7 +267,7 @@ def sweep_mode(self) -> SweepMode: return SweepMode.Unknown @property - @setting("Fan Speed", setter_name="set_fanspeed", choices=FanSpeed, icon="mdi:fan") + @setting("Fan Speed", setter_name="set_fanspeed", choices=FanSpeed) def fan_speed(self) -> FanSpeed: """Current fan speed.""" try: @@ -280,7 +281,6 @@ def fan_speed(self) -> FanSpeed: "Sweep Type", setter_name="set_sweep_type", choices=SweepType, - icon="mdi:robot-vacuum", ) def sweep_type(self) -> SweepType: """Current sweep type sweep/mop/sweep&mop.""" @@ -295,7 +295,6 @@ def sweep_type(self) -> SweepType: "Path Mode", setter_name="set_path_mode", choices=PathMode, - icon="mdi:map-marker-path", ) def path_mode(self) -> PathMode: """Current path-mode: normal/y-mopping etc.""" @@ -306,7 +305,7 @@ def path_mode(self) -> PathMode: return PathMode.Unknown @property - @sensor("Mop Attached", icon="mdi:robot-vacuum-variant") + @sensor("Mop Attached") def is_mop_attached(self) -> bool: """Return True if mop is attached.""" return self.data["mop_present"] @@ -318,7 +317,6 @@ def is_mop_attached(self) -> bool: min_value=0, max_value=3, step=1, - icon="mdi:delete-variant", ) def dust_collection_frequency(self) -> int: """Frequency for emptying the dust bin. @@ -328,7 +326,7 @@ def dust_collection_frequency(self) -> int: return self.data["work_station_freq"] @property - @setting("Timing", setter_name="set_timing", icon="mdi:clock-outline") + @setting("Timing", setter_name="set_timing") def timing(self) -> str: """Repeated cleaning. @@ -366,7 +364,7 @@ def timing(self) -> str: return self.data["timing"] @property - @setting("Carpet Mode", setter_name="set_carpet_mode", icon="mdi:rug") + @setting("Carpet Mode", setter_name="set_carpet_mode") def carpet_mode(self) -> bool: """Auto boost on carpet.""" return self.data["auto_boost"] @@ -393,7 +391,7 @@ def _seconds_to_components(val): ) @property - @sensor("DND Status", icon="mdi:minus-circle") + @sensor("DND Status") def dnd_status(self) -> DNDStatus: """Returns do-not-disturb status.""" return self._parse_forbid_mode(self.data["forbid_mode"]) @@ -403,7 +401,6 @@ def dnd_status(self) -> DNDStatus: "Water Level", setter_name="set_water_level", choices=WaterLevel, - icon="mdi:water", ) def water_level(self) -> WaterLevel: """Get current water level.""" @@ -414,13 +411,13 @@ def water_level(self) -> WaterLevel: return WaterLevel.Unknown @property - @setting("Double Clean", setter_name="set_double_clean", icon="mdi:refresh") + @setting("Double Clean", setter_name="set_double_clean") def double_clean(self) -> bool: """Is double clean enabled.""" return self.data["double_clean"] @property - @setting("LED", setter_name="set_led", icon="mdi:led-on") + @setting("LED", setter_name="set_led") def led(self) -> bool: """Return True if led/display on vaccum is on.""" return self.data["led_switch"] @@ -429,7 +426,6 @@ def led(self) -> bool: @setting( "Lidar Collision Sensor", setter_name="set_lidar_collision_sensor", - icon="mdi:radar", ) def is_lidar_collision_sensor(self) -> bool: """When ON, the robot will use lidar as the main detection sensor to help reduce @@ -437,19 +433,19 @@ def is_lidar_collision_sensor(self) -> bool: return self.data["lidar_collision"] @property - @sensor("Station Key", icon="mdi:gesture-tap-button") + @sensor("Station Key") def station_key(self) -> bool: """When ON: long press the display will turn on dust collection.""" return self.data["station_key"] @property - @setting("Station LED", setter_name="set_station_led", icon="mdi:led-on") + @setting("Station LED", setter_name="set_station_led") def station_led(self) -> bool: """Return if station display is on.""" return self.data["station_led"] @property - @sensor("Current Audio", icon="mdi:account-voice") + @sensor("Current Audio") def current_audio(self) -> str: """Current voice setting. @@ -458,25 +454,25 @@ def current_audio(self) -> str: return self.data["current_audio"] @property - @sensor("Clean Time", icon="mdi:timer-outline") + @sensor("Clean Time") def clean_time(self) -> timedelta: """Time used for cleaning (if finished, shows how long it took).""" return timedelta(seconds=self.data["clean_time_sec"]) @property - @sensor("Clean Area", unit="m²", icon="mdi:texture-box") + @sensor("Clean Area", unit="m²") def clean_area(self) -> int: """Cleaned area in m2.""" return self.data["clean_area"] @property - @sensor("State Code", icon="mdi:robot-vacuum") + @sensor("State Code") def state_code(self) -> int: """State code as returned by the device.""" return int(self.data["state"]) @property - @sensor("State", icon="mdi:robot-vacuum") + @sensor("State") def state(self) -> RoidmiState: """Human readable state description, see also :func:`state_code`.""" try: @@ -493,32 +489,31 @@ def state(self) -> RoidmiState: min_value=0, max_value=100, step=1, - icon="mdi:volume-high", ) def volume(self) -> int: """Return device sound volumen level.""" return self.data["volume"] @property - @setting("Muted", setter_name="set_sound_muted", icon="mdi:volume-off") + @setting("Muted", setter_name="set_sound_muted") def is_muted(self) -> bool: """True if device is muted.""" return bool(self.data["mute"]) @property - @sensor("Is Paused", icon="mdi:pause-circle") + @sensor("Is Paused") def is_paused(self) -> bool: """Return True if vacuum is paused.""" return self.state in [RoidmiState.Paused, RoidmiState.FindChargerPause] @property - @sensor("Is On", icon="mdi:robot-vacuum") + @sensor("Is On") def is_on(self) -> bool: """True if device is currently cleaning in any mode.""" return self.state == RoidmiState.Sweeping @property - @sensor("Got Error", icon="mdi:alert-circle") + @sensor("Got Error") def got_error(self) -> bool: """True if an error has occurred.""" return self.error_code != 0 @@ -531,19 +526,19 @@ def __init__(self, data) -> None: self.data = data @property - @sensor("Total Duration", icon="mdi:timer-outline") + @sensor("Total Duration") def total_duration(self) -> timedelta: """Total cleaning duration.""" return timedelta(seconds=self.data["total_clean_time_sec"]) @property - @sensor("Total Area", unit="m²", icon="mdi:texture-box") + @sensor("Total Area", unit="m²") def total_area(self) -> int: """Total cleaned area.""" return self.data["total_clean_areas"] @property - @sensor("Count", icon="mdi:counter") + @sensor("Count") def count(self) -> int: """Number of cleaning runs.""" return self.data["clean_counts"] @@ -567,19 +562,19 @@ def _calcUsageTime( return original_total * (1 - remaning_fraction) @property - @sensor("Filter Usage", icon="mdi:filter-outline") + @sensor("Filter Usage") def filter(self) -> timedelta: """Filter usage time.""" return self._calcUsageTime(self.filter_left, self.data["filter_life_level"]) @property - @sensor("Filter Left", icon="mdi:filter-outline") + @sensor("Filter Left") def filter_left(self) -> timedelta: """How long until the filter should be changed.""" return timedelta(minutes=self.data["filter_left_minutes"]) @property - @sensor("Main Brush Usage", icon="mdi:brush") + @sensor("Main Brush Usage") def main_brush(self) -> timedelta: """Main brush usage time.""" return self._calcUsageTime( @@ -587,13 +582,13 @@ def main_brush(self) -> timedelta: ) @property - @sensor("Main Brush Left", icon="mdi:brush") + @sensor("Main Brush Left") def main_brush_left(self) -> timedelta: """How long until the main brush should be changed.""" return timedelta(minutes=self.data["main_brush_left_minutes"]) @property - @sensor("Side Brush Usage", icon="mdi:brush") + @sensor("Side Brush Usage") def side_brush(self) -> timedelta: """Main brush usage time.""" return self._calcUsageTime( @@ -601,13 +596,13 @@ def side_brush(self) -> timedelta: ) @property - @sensor("Side Brush Left", icon="mdi:brush") + @sensor("Side Brush Left") def side_brush_left(self) -> timedelta: """How long until the side brushes should be changed.""" return timedelta(minutes=self.data["side_brushes_left_minutes"]) @property - @sensor("Sensor Dirty", icon="mdi:eye-off") + @sensor("Sensor Dirty") def sensor_dirty(self) -> timedelta: """Return time since last sensor clean.""" return self._calcUsageTime( @@ -615,7 +610,7 @@ def sensor_dirty(self) -> timedelta: ) @property - @sensor("Sensor Dirty Left", icon="mdi:eye-off") + @sensor("Sensor Dirty Left") def sensor_dirty_left(self) -> timedelta: """How long until the sensors should be cleaned.""" return timedelta(minutes=self.data["sensor_dirty_time_left_minutes"]) diff --git a/miio/integrations/shuii/humidifier/airhumidifier_jsq.py b/miio/integrations/shuii/humidifier/airhumidifier_jsq.py index 7457d3460..0c4e61a86 100644 --- a/miio/integrations/shuii/humidifier/airhumidifier_jsq.py +++ b/miio/integrations/shuii/humidifier/airhumidifier_jsq.py @@ -60,13 +60,13 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @sensor(name="Power", icon="mdi:power") + @sensor(name="Power") def power(self) -> str: """Power state.""" return "on" if self.data["power"] == 1 else "off" @property - @setting(name="Power", setter_name="on", icon="mdi:power") + @setting(name="Power", setter_name="on") def is_on(self) -> bool: """True if device is turned on.""" return self.power == "on" @@ -75,7 +75,6 @@ def is_on(self) -> bool: @setting( name="Mode", setter_name="set_mode", - icon="mdi:fan", choices=OperationMode, ) def mode(self) -> OperationMode: @@ -105,7 +104,7 @@ def humidity(self) -> int: return self.data["humidity"] @property - @setting(name="Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") + @setting(name="Buzzer", setter_name="set_buzzer") def buzzer(self) -> bool: """True if buzzer is turned on.""" return self.data["buzzer"] == 1 @@ -114,7 +113,6 @@ def buzzer(self) -> bool: @setting( name="LED Brightness", setter_name="set_led_brightness", - icon="mdi:brightness-6", choices=LedBrightness, ) def led_brightness(self) -> LedBrightness: @@ -128,31 +126,31 @@ def led_brightness(self) -> LedBrightness: return brightness @property - @setting(name="LED", setter_name="set_led", icon="mdi:led-outline") + @setting(name="LED", setter_name="set_led") def led(self) -> bool: """True if LED is turned on.""" return self.led_brightness is not LedBrightness.Off @property - @setting(name="Child Lock", setter_name="set_child_lock", icon="mdi:lock") + @setting(name="Child Lock", setter_name="set_child_lock") def child_lock(self) -> bool: """Return True if child lock is on.""" return self.data["child_lock"] == 1 @property - @sensor(name="No Water", icon="mdi:water-off") + @sensor(name="No Water") def no_water(self) -> bool: """True if the water tank is empty.""" return self.data["no_water"] == 1 @property - @sensor(name="Lid Opened", icon="mdi:cup-water") + @sensor(name="Lid Opened") def lid_opened(self) -> bool: """True if the water tank is detached.""" return self.data["lid_opened"] == 1 @property - @sensor(name="Use Time", unit="s", icon="mdi:timer") + @sensor(name="Use Time", unit="s") def use_time(self) -> int | None: """How long the device has been active in seconds. diff --git a/miio/integrations/tinymu/toiletlid/toiletlid.py b/miio/integrations/tinymu/toiletlid/toiletlid.py index 45cb54e56..e657e2be6 100644 --- a/miio/integrations/tinymu/toiletlid/toiletlid.py +++ b/miio/integrations/tinymu/toiletlid/toiletlid.py @@ -42,24 +42,24 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @sensor("Work State", icon="mdi:state-machine") + @sensor("Work State") def work_state(self) -> int: """Device state code.""" return self.data["work_state"] @property - @sensor("Work Mode", icon="mdi:toilet") + @sensor("Work Mode") def work_mode(self) -> ToiletlidOperatingMode: """Device working mode.""" return ToiletlidOperatingMode((self.work_state - 1) // 16) @property - @sensor("Power", icon="mdi:power") + @sensor("Power") def is_on(self) -> bool: return self.work_state != 1 @property - @sensor("Filter Life Remaining", icon="mdi:filter") + @sensor("Filter Life Remaining") def filter_use_percentage(self) -> str: """Filter percentage of remaining life.""" return "{}%".format(self.data["filter_use_flux"]) @@ -68,7 +68,6 @@ def filter_use_percentage(self) -> str: @sensor( "Filter Remaining Time", unit="d", - icon="mdi:filter-outline", device_class="duration", ) def filter_remaining_time(self) -> int: @@ -79,7 +78,6 @@ def filter_remaining_time(self) -> int: @setting( "Ambient Light", setter_name="set_ambient_light", - icon="mdi:lightbulb-variant", choices=AmbientLightColor, ) def ambient_light(self) -> str: diff --git a/miio/integrations/viomi/viomidishwasher/viomidishwasher.py b/miio/integrations/viomi/viomidishwasher/viomidishwasher.py index ba729cb10..ae6ac3968 100644 --- a/miio/integrations/viomi/viomidishwasher/viomidishwasher.py +++ b/miio/integrations/viomi/viomidishwasher/viomidishwasher.py @@ -104,7 +104,7 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @setting(name="Child Lock", setter_name="child_lock", icon="mdi:lock") + @setting(name="Child Lock", setter_name="child_lock") def child_lock(self) -> bool: """Returns the child lock status of the device.""" value = self.data["child_lock"] @@ -117,7 +117,6 @@ def child_lock(self) -> bool: @setting( name="Program", setter_name="start", - icon="mdi:dishwasher", choices=Program, ) def program(self) -> Program: @@ -130,14 +129,14 @@ def program(self) -> Program: return Program.Unknown @property - @sensor(name="Door Open", icon="mdi:door-open") + @sensor(name="Door Open") def door_open(self) -> bool: """Returns True if the door is open.""" return bool(self.data["run_status"] & (1 << 7)) @property - @sensor(name="System Status Raw", icon="mdi:information-outline") + @sensor(name="System Status Raw") def system_status_raw(self) -> int: """Returns the raw status number of the device. @@ -149,7 +148,7 @@ def system_status_raw(self) -> int: return self.data["run_status"] @property - @sensor(name="Status", icon="mdi:dishwasher") + @sensor(name="Status") def status(self) -> MachineStatus: """Returns the machine status of the device.""" @@ -164,7 +163,7 @@ def temperature(self) -> int: return self.data["wash_temp"] @property - @setting(name="Power", setter_name="on", icon="mdi:power") + @setting(name="Power", setter_name="on") def power(self) -> bool: """Returns the power status of the device.""" @@ -175,7 +174,7 @@ def power(self) -> bool: raise DeviceException(f"{value} is not a valid power status.") @property - @sensor(name="Time Left", icon="mdi:timer") + @sensor(name="Time Left") def time_left(self) -> timedelta: """Returns the timedelta in seconds of time left of the current program. @@ -188,7 +187,7 @@ def time_left(self) -> timedelta: raise DeviceException(f"{value} is not a valid integer for time_left.") @property - @sensor(name="Schedule", icon="mdi:calendar-clock") + @sensor(name="Schedule") def schedule(self) -> datetime | None: """Returns a datetime when the scheduled program should be finished. @@ -204,7 +203,7 @@ def schedule(self) -> datetime | None: ) @property - @setting(name="Air Refresh Interval", setter_name="airrefresh", icon="mdi:fan") + @setting(name="Air Refresh Interval", setter_name="airrefresh") def air_refresh_interval(self) -> int: """Returns an integer on how often the air in the device should be refreshed. @@ -219,7 +218,7 @@ def air_refresh_interval(self) -> int: raise DeviceException(f"{value} is not a valid integer for freshdry_interval.") @property - @sensor(name="Program Progress", icon="mdi:progress-check") + @sensor(name="Program Progress") def program_progress(self) -> ProgramStatus: """Returns the program status of the running program.""" value = self.data["wash_process"] @@ -230,7 +229,7 @@ def program_progress(self) -> ProgramStatus: return ProgramStatus.Unknown @property - @sensor(name="Errors", icon="mdi:alert-circle") + @sensor(name="Errors") def errors(self) -> list[SystemStatus]: """Returns list of errors if detected in the system.""" diff --git a/miio/integrations/xiaomi/aircondition/airconditioner_miot.py b/miio/integrations/xiaomi/aircondition/airconditioner_miot.py index 84106081c..25d025756 100644 --- a/miio/integrations/xiaomi/aircondition/airconditioner_miot.py +++ b/miio/integrations/xiaomi/aircondition/airconditioner_miot.py @@ -81,17 +81,17 @@ def __init__(self, status: str): self.status = [int(value) for value in status.split(",")] @property - @sensor("Cleaning", icon="mdi:broom") + @sensor("Cleaning") def cleaning(self) -> bool: return bool(self.status[0]) @property - @sensor("Progress", unit="%", icon="mdi:progress-check") + @sensor("Progress", unit="%") def progress(self) -> int: return int(self.status[1]) @property - @sensor("Stage", icon="mdi:broom") + @sensor("Stage") def stage(self) -> str: try: return CLEANING_STAGES[self.status[2]] @@ -99,7 +99,7 @@ def stage(self) -> str: return "Unknown stage" @property - @sensor("Cancellable", icon="mdi:cancel") + @sensor("Cancellable") def cancellable(self) -> bool: return bool(self.status[3]) @@ -145,22 +145,22 @@ def __init__(self, status): self.status = [int(value) for value in status.split(",")] @property - @sensor("Enabled", icon="mdi:timer") + @sensor("Enabled") def enabled(self) -> bool: return bool(self.status[0]) @property - @sensor("Countdown", icon="mdi:timer-outline") + @sensor("Countdown") def countdown(self) -> timedelta: return timedelta(minutes=self.status[1]) @property - @sensor("Power On", icon="mdi:power") + @sensor("Power On") def power_on(self) -> bool: return bool(self.status[2]) @property - @sensor("Time Left", icon="mdi:timer-outline") + @sensor("Time Left") def time_left(self) -> timedelta: return timedelta(minutes=self.status[3]) @@ -195,13 +195,13 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @sensor("Is On", icon="mdi:power") + @sensor("Is On") def is_on(self) -> bool: """True if the device is turned on.""" return self.data["power"] @property - @sensor("Power", icon="mdi:power") + @sensor("Power") def power(self) -> str: """Current power state.""" return "on" if self.is_on else "off" @@ -211,7 +211,6 @@ def power(self) -> str: "Mode", setter_name="set_mode", choices=OperationMode, - icon="mdi:air-conditioner", ) def mode(self) -> OperationMode: """Current operation mode.""" @@ -226,84 +225,79 @@ def mode(self) -> OperationMode: max_value=31, step=1, device_class="temperature", - icon="mdi:thermometer", ) def target_temperature(self) -> float: """Target temperature in Celsius.""" return self.data["target_temperature"] @property - @setting("ECO", setter_name="set_eco", icon="mdi:leaf") + @setting("ECO", setter_name="set_eco") def eco(self) -> bool: """True if ECO mode is on.""" return self.data["eco"] @property - @setting("Heater", setter_name="set_heater", icon="mdi:radiator") + @setting("Heater", setter_name="set_heater") def heater(self) -> bool: """True if aux heat mode is on.""" return self.data["heater"] @property - @setting("Dryer", setter_name="set_dryer", icon="mdi:water-off") + @setting("Dryer", setter_name="set_dryer") def dryer(self) -> bool: """True if aux dryer mode is on.""" return self.data["dryer"] @property - @setting("Sleep Mode", setter_name="set_sleep_mode", icon="mdi:sleep") + @setting("Sleep Mode", setter_name="set_sleep_mode") def sleep_mode(self) -> bool: """True if sleep mode is on.""" return self.data["sleep_mode"] @property - @setting("Fan Speed", setter_name="set_fan_speed", choices=FanSpeed, icon="mdi:fan") + @setting("Fan Speed", setter_name="set_fan_speed", choices=FanSpeed) def fan_speed(self) -> FanSpeed: """Current Fan speed.""" return FanSpeed(self.data["fan_speed"]) @property - @setting( - "Vertical Swing", setter_name="set_vertical_swing", icon="mdi:arrow-up-down" - ) + @setting("Vertical Swing", setter_name="set_vertical_swing") def vertical_swing(self) -> bool: """True if vertical swing is on.""" return self.data["vertical_swing"] @property - @sensor( - "Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer" - ) + @sensor("Temperature", unit="°C", device_class="temperature") def temperature(self) -> float: """Current ambient temperature in Celsius.""" return self.data["temperature"] @property - @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") + @setting("Buzzer", setter_name="set_buzzer") def buzzer(self) -> bool: """True if buzzer is on.""" return self.data["buzzer"] @property - @setting("LED", setter_name="set_led", icon="mdi:led-on") + @setting("LED", setter_name="set_led") def led(self) -> bool: """True if LED is on.""" return self.data["led"] @property - @sensor("Electricity", unit="kWh", device_class="energy", icon="mdi:flash") + @sensor("Electricity", unit="kWh", device_class="energy") def electricity(self) -> float: """Power consumption accumulation in kWh.""" return self.data["electricity"] @property - @sensor("Clean", icon="mdi:broom") + @sensor("Clean") def clean(self) -> CleaningStatus: """Auto clean mode indicator.""" return CleaningStatus(self.data["clean"]) @property - @sensor("Total Running Duration", icon="mdi:timer-outline") + @sensor("Total Running Duration") def total_running_duration(self) -> timedelta: """Total running duration in hours.""" return timedelta(hours=self.data["running_duration"]) @@ -316,14 +310,13 @@ def total_running_duration(self) -> timedelta: min_value=1, max_value=101, step=1, - icon="mdi:fan", ) def fan_speed_percent(self) -> int: """Current fan speed in percent.""" return self.data["fan_speed_percent"] @property - @sensor("Timer", icon="mdi:timer") + @sensor("Timer") def timer(self) -> TimerStatus: """Countdown timer indicator.""" return TimerStatus(self.data["timer"]) diff --git a/miio/integrations/xiaomi/repeater/wifirepeater.py b/miio/integrations/xiaomi/repeater/wifirepeater.py index 4fee888a8..adc586006 100644 --- a/miio/integrations/xiaomi/repeater/wifirepeater.py +++ b/miio/integrations/xiaomi/repeater/wifirepeater.py @@ -26,13 +26,13 @@ def __init__(self, data): self.data = data @property - @sensor("Access Policy", icon="mdi:security") + @sensor("Access Policy") def access_policy(self) -> int: """Access policy of the associated stations.""" return self.data["sta"]["access_policy"] @property - @sensor("Associated Stations", icon="mdi:devices") + @sensor("Associated Stations") def associated_stations(self) -> dict: """List of associated stations.""" return self.data["mat"] @@ -54,17 +54,17 @@ def __init__(self, data): self.data = data @property - @sensor("SSID", icon="mdi:wifi") + @sensor("SSID") def ssid(self) -> str: return self.data["ssid"] @property - @sensor("Password", icon="mdi:lock") + @sensor("Password") def password(self) -> str: return self.data["pwd"] @property - @sensor("SSID Hidden", icon="mdi:wifi-off") + @sensor("SSID Hidden") def ssid_hidden(self) -> bool: return self.data["hidden"] == 1 diff --git a/miio/integrations/xiaomi/wifispeaker/wifispeaker.py b/miio/integrations/xiaomi/wifispeaker/wifispeaker.py index d2aeda925..13a633a3b 100644 --- a/miio/integrations/xiaomi/wifispeaker/wifispeaker.py +++ b/miio/integrations/xiaomi/wifispeaker/wifispeaker.py @@ -47,56 +47,56 @@ def __init__(self, data): self.data = data @property - @sensor("Device Name", icon="mdi:speaker") + @sensor("Device Name") def device_name(self) -> str: """Name of the device.""" return self.data["DeviceName"] @property - @sensor("Channel", icon="mdi:radio") + @sensor("Channel") def channel(self) -> str: """Name of the channel.""" return self.data["channel_title"] @property - @sensor("State", icon="mdi:play-circle") + @sensor("State") def state(self) -> PlayState: """State of the device, e.g. PLAYING.""" return PlayState(self.data["current_state"]) @property - @sensor("Hardware Version", icon="mdi:information-outline") + @sensor("Hardware Version") def hardware_version(self) -> str: """Hardware version.""" return self.data["hardware_version"] @property - @sensor("Play Mode", icon="mdi:repeat") + @sensor("Play Mode") def play_mode(self) -> str: """Play mode such as REPEAT_ALL.""" # note: this can be enumized when all values are known return self.data["play_mode"] @property - @sensor("Track Artist", icon="mdi:account-music") + @sensor("Track Artist") def track_artist(self) -> str: """Artist of the current track.""" return self.data["track_artist"] @property - @sensor("Track Title", icon="mdi:music-note") + @sensor("Track Title") def track_title(self) -> str: """Title of the current track.""" return self.data["track_title"] @property - @sensor("Track Duration", icon="mdi:timer-music", device_class="duration") + @sensor("Track Duration", device_class="duration") def track_duration(self) -> str: """Total duration of the current track.""" return self.data["track_duration"] @property - @sensor("Transport Channel", icon="mdi:radio") + @sensor("Transport Channel") def transport_channel(self) -> TransportChannel: """Transport channel, e.g. PLAYLIST.""" return TransportChannel(self.data["transport_channel"]) diff --git a/miio/integrations/yeelight/dual_switch/yeelight_dual_switch.py b/miio/integrations/yeelight/dual_switch/yeelight_dual_switch.py index 2dda932a4..70ce6a664 100644 --- a/miio/integrations/yeelight/dual_switch/yeelight_dual_switch.py +++ b/miio/integrations/yeelight/dual_switch/yeelight_dual_switch.py @@ -62,7 +62,7 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @sensor("Switch 1 State", icon="mdi:toggle-switch") + @sensor("Switch 1 State") def switch_1_state(self) -> bool: """First switch state.""" return bool(self.data["switch_1_state"]) @@ -71,7 +71,6 @@ def switch_1_state(self) -> bool: @setting( "Switch 1 Default State", setter_name="set_default_state", - icon="mdi:toggle-switch-outline", ) def switch_1_default_state(self) -> bool: """First switch default state.""" @@ -81,7 +80,6 @@ def switch_1_default_state(self) -> bool: @setting( "Switch 1 Off Delay", setter_name="set_switch_off_delay", - icon="mdi:timer", device_class="duration", unit="s", min_value=-1, @@ -93,7 +91,7 @@ def switch_1_off_delay(self) -> int: return self.data["switch_1_off_delay"] @property - @sensor("Switch 2 State", icon="mdi:toggle-switch") + @sensor("Switch 2 State") def switch_2_state(self) -> bool: """Second switch state.""" return bool(self.data["switch_2_state"]) @@ -102,7 +100,6 @@ def switch_2_state(self) -> bool: @setting( "Switch 2 Default State", setter_name="set_default_state", - icon="mdi:toggle-switch-outline", ) def switch_2_default_state(self) -> bool: """Second switch default state.""" @@ -112,7 +109,6 @@ def switch_2_default_state(self) -> bool: @setting( "Switch 2 Off Delay", setter_name="set_switch_off_delay", - icon="mdi:timer", device_class="duration", unit="s", min_value=-1, @@ -124,19 +120,19 @@ def switch_2_off_delay(self) -> int: return self.data["switch_2_off_delay"] @property - @setting("Interlock", setter_name="set_interlock", icon="mdi:lock-outline") + @setting("Interlock", setter_name="set_interlock") def interlock(self) -> bool: """Interlock.""" return bool(self.data["interlock"]) @property - @setting("Flex Mode", setter_name="set_flex_mode", icon="mdi:shuffle-variant") + @setting("Flex Mode", setter_name="set_flex_mode") def flex_mode(self) -> int: """Flex mode.""" return self.data["flex_mode"] @property - @sensor("RC List", icon="mdi:remote") + @sensor("RC List") def rc_list(self) -> str: """List of paired remote controls.""" return self.data["rc_list"] diff --git a/miio/integrations/yunmi/waterpurifier/waterpurifier.py b/miio/integrations/yunmi/waterpurifier/waterpurifier.py index c6707a7b6..4e5640bc2 100644 --- a/miio/integrations/yunmi/waterpurifier/waterpurifier.py +++ b/miio/integrations/yunmi/waterpurifier/waterpurifier.py @@ -15,98 +15,96 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @sensor("Power", icon="mdi:power") + @sensor("Power") def power(self) -> str: return self.data["power"] @property - @sensor("Is On", icon="mdi:power") + @sensor("Is On") def is_on(self) -> bool: return self.power == "on" @property - @sensor("Mode", icon="mdi:water") + @sensor("Mode") def mode(self) -> str: """Current operation mode.""" return self.data["mode"] @property - @sensor("TDS", unit="ppm", icon="mdi:water-opacity") + @sensor("TDS", unit="ppm") def tds(self) -> str: return self.data["tds"] @property - @sensor("Filter Life Remaining", unit="%", icon="mdi:filter") + @sensor("Filter Life Remaining", unit="%") def filter_life_remaining(self) -> int: """Time until the filter should be changed.""" return self.data["filter1_life"] @property - @sensor("Filter State", icon="mdi:filter") + @sensor("Filter State") def filter_state(self) -> str: return self.data["filter1_state"] @property - @sensor("Filter 2 Life Remaining", unit="%", icon="mdi:filter") + @sensor("Filter 2 Life Remaining", unit="%") def filter2_life_remaining(self) -> int: """Time until the filter should be changed.""" return self.data["filter_life"] @property - @sensor("Filter 2 State", icon="mdi:filter") + @sensor("Filter 2 State") def filter2_state(self) -> str: return self.data["filter_state"] @property - @sensor("Life", icon="mdi:clock-outline") + @sensor("Life") def life(self) -> str: return self.data["life"] @property - @sensor("State", icon="mdi:information-outline") + @sensor("State") def state(self) -> str: return self.data["state"] @property - @sensor("Level", icon="mdi:water") + @sensor("Level") def level(self) -> str: return self.data["level"] @property - @sensor("Volume", icon="mdi:cup-water") + @sensor("Volume") def volume(self) -> str: return self.data["volume"] @property - @sensor("Filter", icon="mdi:filter") + @sensor("Filter") def filter(self) -> str: return self.data["filter"] @property - @sensor("Usage", icon="mdi:chart-line") + @sensor("Usage") def usage(self) -> str: return self.data["usage"] @property - @sensor( - "Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer" - ) + @sensor("Temperature", unit="°C", device_class="temperature") def temperature(self) -> str: return self.data["temperature"] @property - @sensor("UV Filter Life Remaining", unit="%", icon="mdi:filter") + @sensor("UV Filter Life Remaining", unit="%") def uv_filter_life_remaining(self) -> int: """Time until the filter should be changed.""" return self.data["uv_life"] @property - @sensor("UV Filter State", icon="mdi:filter") + @sensor("UV Filter State") def uv_filter_state(self) -> str: return self.data["uv_state"] @property - @sensor("Valve", icon="mdi:valve") + @sensor("Valve") def valve(self) -> str: return self.data["elecval_state"] diff --git a/miio/integrations/yunmi/waterpurifier/waterpurifier_yunmi.py b/miio/integrations/yunmi/waterpurifier/waterpurifier_yunmi.py index a6b2ec8a4..e3a178335 100644 --- a/miio/integrations/yunmi/waterpurifier/waterpurifier_yunmi.py +++ b/miio/integrations/yunmi/waterpurifier/waterpurifier_yunmi.py @@ -96,7 +96,7 @@ def __init__(self, operation_status: int): ] @property - @sensor("Errors", icon="mdi:alert-circle") + @sensor("Errors") def errors(self) -> list: return self.err_list @@ -121,147 +121,145 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @sensor("Operation Status", icon="mdi:information-outline") + @sensor("Operation Status") def operation_status(self) -> OperationStatus: """Current operation status.""" return OperationStatus(self.data["run_status"]) @property - @sensor("Filter 1 Life Total", icon="mdi:filter-outline") + @sensor("Filter 1 Life Total") def filter1_life_total(self) -> timedelta: """Filter1 total available time in hours.""" return timedelta(hours=self.data["f1_totaltime"]) @property - @sensor("Filter 1 Life Used", icon="mdi:filter-outline") + @sensor("Filter 1 Life Used") def filter1_life_used(self) -> timedelta: """Filter1 used time in hours.""" return timedelta(hours=self.data["f1_usedtime"]) @property - @sensor("Filter 1 Life Remaining", icon="mdi:filter-outline") + @sensor("Filter 1 Life Remaining") def filter1_life_remaining(self) -> timedelta: """Filter1 remaining time in hours.""" return self.filter1_life_total - self.filter1_life_used @property - @sensor("Filter 1 Flow Total", unit="L", icon="mdi:water") + @sensor("Filter 1 Flow Total", unit="L") def filter1_flow_total(self) -> int: """Filter1 total available flow in Metric Liter (L).""" return self.data["f1_totalflow"] @property - @sensor("Filter 1 Flow Used", unit="L", icon="mdi:water") + @sensor("Filter 1 Flow Used", unit="L") def filter1_flow_used(self) -> int: """Filter1 used flow in Metric Liter (L).""" return self.data["f1_usedflow"] @property - @sensor("Filter 1 Flow Remaining", unit="L", icon="mdi:water") + @sensor("Filter 1 Flow Remaining", unit="L") def filter1_flow_remaining(self) -> int: """Filter1 remaining flow in Metric Liter (L).""" return self.filter1_flow_total - self.filter1_flow_used @property - @sensor("Filter 2 Life Total", icon="mdi:filter-outline") + @sensor("Filter 2 Life Total") def filter2_life_total(self) -> timedelta: """Filter2 total available time in hours.""" return timedelta(hours=self.data["f2_totaltime"]) @property - @sensor("Filter 2 Life Used", icon="mdi:filter-outline") + @sensor("Filter 2 Life Used") def filter2_life_used(self) -> timedelta: """Filter2 used time in hours.""" return timedelta(hours=self.data["f2_usedtime"]) @property - @sensor("Filter 2 Life Remaining", icon="mdi:filter-outline") + @sensor("Filter 2 Life Remaining") def filter2_life_remaining(self) -> timedelta: """Filter2 remaining time in hours.""" return self.filter2_life_total - self.filter2_life_used @property - @sensor("Filter 2 Flow Total", unit="L", icon="mdi:water") + @sensor("Filter 2 Flow Total", unit="L") def filter2_flow_total(self) -> int: """Filter2 total available flow in Metric Liter (L).""" return self.data["f2_totalflow"] @property - @sensor("Filter 2 Flow Used", unit="L", icon="mdi:water") + @sensor("Filter 2 Flow Used", unit="L") def filter2_flow_used(self) -> int: """Filter2 used flow in Metric Liter (L).""" return self.data["f2_usedflow"] @property - @sensor("Filter 2 Flow Remaining", unit="L", icon="mdi:water") + @sensor("Filter 2 Flow Remaining", unit="L") def filter2_flow_remaining(self) -> int: """Filter2 remaining flow in Metric Liter (L).""" return self.filter2_flow_total - self.filter2_flow_used @property - @sensor("Filter 3 Life Total", icon="mdi:filter-outline") + @sensor("Filter 3 Life Total") def filter3_life_total(self) -> timedelta: """Filter3 total available time in hours.""" return timedelta(hours=self.data["f3_totaltime"]) @property - @sensor("Filter 3 Life Used", icon="mdi:filter-outline") + @sensor("Filter 3 Life Used") def filter3_life_used(self) -> timedelta: """Filter3 used time in hours.""" return timedelta(hours=self.data["f3_usedtime"]) @property - @sensor("Filter 3 Life Remaining", icon="mdi:filter-outline") + @sensor("Filter 3 Life Remaining") def filter3_life_remaining(self) -> timedelta: """Filter3 remaining time in hours.""" return self.filter3_life_total - self.filter3_life_used @property - @sensor("Filter 3 Flow Total", unit="L", icon="mdi:water") + @sensor("Filter 3 Flow Total", unit="L") def filter3_flow_total(self) -> int: """Filter3 total available flow in Metric Liter (L).""" return self.data["f3_totalflow"] @property - @sensor("Filter 3 Flow Used", unit="L", icon="mdi:water") + @sensor("Filter 3 Flow Used", unit="L") def filter3_flow_used(self) -> int: """Filter3 used flow in Metric Liter (L).""" return self.data["f3_usedflow"] @property - @sensor("Filter 3 Flow Remaining", unit="L", icon="mdi:water") + @sensor("Filter 3 Flow Remaining", unit="L") def filter3_flow_remaining(self) -> int: """Filter1 remaining flow in Metric Liter (L).""" return self.filter3_flow_total - self.filter3_flow_used @property - @sensor("TDS In", unit="ppm", icon="mdi:water-check") + @sensor("TDS In", unit="ppm") def tds_in(self) -> int: """TDS value of input water.""" return self.data["tds_in"] @property - @sensor("TDS Out", unit="ppm", icon="mdi:water-check") + @sensor("TDS Out", unit="ppm") def tds_out(self) -> int: """TDS value of output water.""" return self.data["tds_out"] @property - @sensor("Rinse", icon="mdi:water-sync") + @sensor("Rinse") def rinse(self) -> bool: """True if the device is rinsing.""" return self.data["rinse"] @property - @sensor( - "Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer" - ) + @sensor("Temperature", unit="°C", device_class="temperature") def temperature(self) -> int: """Current water temperature in Celsius.""" return self.data["temperature"] @property - @sensor("TDS Warning Threshold", unit="ppm", icon="mdi:water-alert") + @sensor("TDS Warning Threshold", unit="ppm") def tds_warn_thd(self) -> int: """TDS warning threshold.""" return self.data["tds_warn_thd"] diff --git a/miio/integrations/zhimi/airpurifier/airfresh.py b/miio/integrations/zhimi/airpurifier/airfresh.py index 4324a9e7f..6f63ff519 100644 --- a/miio/integrations/zhimi/airpurifier/airfresh.py +++ b/miio/integrations/zhimi/airpurifier/airfresh.py @@ -93,43 +93,43 @@ def __init__(self, data: dict[str, Any], model: str) -> None: self.model = model @property - @sensor("Power", icon="mdi:power") + @sensor("Power") def power(self) -> str: """Power state.""" return self.data["power"] @property - @sensor("Is On", icon="mdi:power") + @sensor("Is On") def is_on(self) -> bool: """Return True if device is on.""" return self.power == "on" @property - @sensor("AQI", unit="μg/m³", icon="mdi:air-filter") + @sensor("AQI", unit="μg/m³") def aqi(self) -> int: """Air quality index.""" return self.data["aqi"] @property - @sensor("Average AQI", unit="μg/m³", icon="mdi:air-filter") + @sensor("Average AQI", unit="μg/m³") def average_aqi(self) -> int: """Average of the air quality index.""" return self.data["average_aqi"] @property - @sensor("CO2", unit="ppm", icon="mdi:molecule-co2", device_class="carbon_dioxide") + @sensor("CO2", unit="ppm", device_class="carbon_dioxide") def co2(self) -> int: """Carbon dioxide.""" return self.data["co2"] @property - @sensor("Humidity", unit="%", device_class="humidity", icon="mdi:water-percent") + @sensor("Humidity", unit="%", device_class="humidity") def humidity(self) -> int: """Current humidity.""" return self.data["humidity"] @property - @setting("PTC", setter_name="set_ptc", icon="mdi:radiator") + @setting("PTC", setter_name="set_ptc") def ptc(self) -> bool | None: """Return True if PTC is on.""" if self.data["ptc_state"] is not None: @@ -138,9 +138,7 @@ def ptc(self) -> bool | None: return None @property - @sensor( - "Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer" - ) + @sensor("Temperature", unit="°C", device_class="temperature") def temperature(self) -> float | None: """Current temperature, if available.""" if self.data["temp_dec"] is not None: @@ -152,9 +150,7 @@ def temperature(self) -> float | None: return None @property - @sensor( - "NTC Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer" - ) + @sensor("NTC Temperature", unit="°C", device_class="temperature") def ntc_temperature(self) -> float | None: """Current ntc temperature, if available.""" if self.data["ntcT"] is not None: @@ -163,24 +159,19 @@ def ntc_temperature(self) -> float | None: return None @property - @setting("Mode", setter_name="set_mode", choices=OperationMode, icon="mdi:fan") + @setting("Mode", setter_name="set_mode", choices=OperationMode) def mode(self) -> OperationMode: """Current operation mode.""" return OperationMode(self.data["mode"]) @property - @setting("LED", setter_name="set_led", icon="mdi:led-on") + @setting("LED", setter_name="set_led") def led(self) -> bool: """Return True if LED is on.""" return self.data["led"] == "on" @property - @setting( - "LED Brightness", - setter_name="set_led_brightness", - choices=LedBrightness, - icon="mdi:brightness-6", - ) + @setting("LED Brightness", setter_name="set_led_brightness", choices=LedBrightness) def led_brightness(self) -> LedBrightness | None: """Brightness of the LED.""" if self.data["led_level"] is not None: @@ -195,7 +186,7 @@ def led_brightness(self) -> LedBrightness | None: return None @property - @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") + @setting("Buzzer", setter_name="set_buzzer") def buzzer(self) -> bool | None: """Return True if buzzer is on.""" if self.data["buzzer"] is not None: @@ -204,37 +195,37 @@ def buzzer(self) -> bool | None: return None @property - @setting("Child Lock", setter_name="set_child_lock", icon="mdi:lock") + @setting("Child Lock", setter_name="set_child_lock") def child_lock(self) -> bool: """Return True if child lock is on.""" return self.data["child_lock"] == "on" @property - @sensor("Filter Life Remaining", unit="%", icon="mdi:filter-outline") + @sensor("Filter Life Remaining", unit="%") def filter_life_remaining(self) -> int: """Time until the filter should be changed.""" return self.data["filter_life"] @property - @sensor("Filter Hours Used", unit="h", icon="mdi:filter-outline") + @sensor("Filter Hours Used", unit="h") def filter_hours_used(self) -> int: """How long the filter has been in use.""" return self.data["f1_hour_used"] @property - @sensor("Use Time", unit="s", icon="mdi:timer-sand") + @sensor("Use Time", unit="s") def use_time(self) -> int: """How long the device has been active in seconds.""" return self.data["use_time"] @property - @sensor("Motor Speed", unit="rpm", icon="mdi:fan") + @sensor("Motor Speed", unit="rpm") def motor_speed(self) -> int: """Speed of the motor.""" return self.data["motor1_speed"] @property - @setting("Extra Features", setter_name="set_extra_features", icon="mdi:star") + @setting("Extra Features", setter_name="set_extra_features") def extra_features(self) -> int | None: return self.data["app_extra"] diff --git a/miio/integrations/zhimi/airpurifier/airpurifier.py b/miio/integrations/zhimi/airpurifier/airpurifier.py index 6495a3a8c..4de1313ff 100644 --- a/miio/integrations/zhimi/airpurifier/airpurifier.py +++ b/miio/integrations/zhimi/airpurifier/airpurifier.py @@ -131,39 +131,37 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @sensor("Power", icon="mdi:power") + @sensor("Power") def power(self) -> str: """Power state.""" return self.data["power"] @property - @sensor("Is On", icon="mdi:power") + @sensor("Is On") def is_on(self) -> bool: """Return True if device is on.""" return self.power == "on" @property - @sensor("AQI", unit="μg/m³", icon="mdi:air-filter") + @sensor("AQI", unit="μg/m³") def aqi(self) -> int: """Air quality index.""" return self.data["aqi"] @property - @sensor("Average AQI", unit="μg/m³", icon="mdi:air-filter") + @sensor("Average AQI", unit="μg/m³") def average_aqi(self) -> int: """Average of the air quality index.""" return self.data["average_aqi"] @property - @sensor("Humidity", unit="%", device_class="humidity", icon="mdi:water-percent") + @sensor("Humidity", unit="%", device_class="humidity") def humidity(self) -> int: """Current humidity.""" return self.data["humidity"] @property - @sensor( - "Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer" - ) + @sensor("Temperature", unit="°C", device_class="temperature") def temperature(self) -> float | None: """Current temperature, if available.""" if self.data["temp_dec"] is not None: @@ -172,15 +170,13 @@ def temperature(self) -> float | None: return None @property - @setting( - "Mode", setter_name="set_mode", choices=OperationMode, icon="mdi:air-purifier" - ) + @setting("Mode", setter_name="set_mode", choices=OperationMode) def mode(self) -> OperationMode: """Current operation mode.""" return OperationMode(self.data["mode"]) @property - @sensor("Sleep Mode", icon="mdi:sleep") + @sensor("Sleep Mode") def sleep_mode(self) -> SleepMode | None: """Operation mode of the sleep state. @@ -192,18 +188,13 @@ def sleep_mode(self) -> SleepMode | None: return None @property - @setting("LED", setter_name="set_led", icon="mdi:led-on") + @setting("LED", setter_name="set_led") def led(self) -> bool: """Return True if LED is on.""" return self.data["led"] == "on" @property - @setting( - "LED Brightness", - setter_name="set_led_brightness", - choices=LedBrightness, - icon="mdi:brightness-6", - ) + @setting("LED Brightness", setter_name="set_led_brightness", choices=LedBrightness) def led_brightness(self) -> LedBrightness | None: """Brightness of the LED.""" if self.data["led_b"] is not None: @@ -215,9 +206,7 @@ def led_brightness(self) -> LedBrightness | None: return None @property - @sensor( - "Illuminance", unit="lx", device_class="illuminance", icon="mdi:brightness-5" - ) + @sensor("Illuminance", unit="lx", device_class="illuminance") def illuminance(self) -> int | None: """Environment illuminance level in lux [0-200]. @@ -226,7 +215,7 @@ def illuminance(self) -> int | None: return self.data["bright"] @property - @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") + @setting("Buzzer", setter_name="set_buzzer") def buzzer(self) -> bool | None: """Return True if buzzer is on.""" if self.data["buzzer"] is not None: @@ -235,7 +224,7 @@ def buzzer(self) -> bool | None: return None @property - @setting("Child Lock", setter_name="set_child_lock", icon="mdi:lock") + @setting("Child Lock", setter_name="set_child_lock") def child_lock(self) -> bool: """Return True if child lock is on.""" return self.data["child_lock"] == "on" @@ -247,7 +236,6 @@ def child_lock(self) -> bool: min_value=0, max_value=17, step=1, - icon="mdi:star", ) def favorite_level(self) -> int: """Return favorite level, which is used if the mode is ``favorite``.""" @@ -255,69 +243,63 @@ def favorite_level(self) -> int: return self.data["favorite_level"] @property - @sensor("Filter Life Remaining", unit="%", icon="mdi:filter-outline") + @sensor("Filter Life Remaining", unit="%") def filter_life_remaining(self) -> int: """Time until the filter should be changed.""" return self.data["filter1_life"] @property - @sensor("Filter Hours Used", unit="h", icon="mdi:filter-outline") + @sensor("Filter Hours Used", unit="h") def filter_hours_used(self) -> int: """How long the filter has been in use.""" return self.data["f1_hour_used"] @property - @sensor("Use Time", unit="s", icon="mdi:timer-sand") + @sensor("Use Time", unit="s") def use_time(self) -> int: """How long the device has been active in seconds.""" return self.data["use_time"] @property - @sensor("Purify Volume", unit="m³", icon="mdi:air-purifier") + @sensor("Purify Volume", unit="m³") def purify_volume(self) -> int: """The volume of purified air in cubic meter.""" return self.data["purify_volume"] @property - @sensor("Motor Speed", unit="rpm", icon="mdi:fan") + @sensor("Motor Speed", unit="rpm") def motor_speed(self) -> int: """Speed of the motor.""" return self.data["motor1_speed"] @property - @sensor("Motor 2 Speed", unit="rpm", icon="mdi:fan") + @sensor("Motor 2 Speed", unit="rpm") def motor2_speed(self) -> int | None: """Speed of the 2nd motor.""" return self.data["motor2_speed"] @property @setting( - "Volume", - setter_name="set_volume", - unit="%", - min_value=0, - max_value=100, - step=1, - icon="mdi:volume-high", + "Volume", setter_name="set_volume", unit="%", min_value=0, max_value=100, step=1 ) def volume(self) -> int | None: """Volume of sound notifications [0-100].""" return self.data["volume"] @property - @sensor("Filter RFID Product ID", icon="mdi:barcode") + @sensor("Filter RFID Product ID") def filter_rfid_product_id(self) -> str | None: """RFID product ID of installed filter.""" return self.data["rfid_product_id"] @property - @sensor("Filter RFID Tag", icon="mdi:barcode") + @sensor("Filter RFID Tag") def filter_rfid_tag(self) -> str | None: """RFID tag ID of installed filter.""" return self.data["rfid_tag"] @property - @sensor("Filter Type", icon="mdi:filter-outline") + @sensor("Filter Type") def filter_type(self) -> FilterType | None: """Type of installed filter.""" return self.filter_type_util.determine_filter_type( @@ -325,28 +307,28 @@ def filter_type(self) -> FilterType | None: ) @property - @setting("Learn Mode", setter_name="set_learn_mode", icon="mdi:school") + @setting("Learn Mode", setter_name="set_learn_mode") def learn_mode(self) -> bool: """Return True if Learn Mode is enabled.""" return self.data["act_sleep"] == "single" @property - @sensor("Sleep Time", unit="s", icon="mdi:sleep") + @sensor("Sleep Time", unit="s") def sleep_time(self) -> int | None: return self.data["sleep_time"] @property - @sensor("Sleep Mode Learn Count", icon="mdi:counter") + @sensor("Sleep Mode Learn Count") def sleep_mode_learn_count(self) -> int | None: return self.data["sleep_data_num"] @property - @setting("Extra Features", setter_name="set_extra_features", icon="mdi:star") + @setting("Extra Features", setter_name="set_extra_features") def extra_features(self) -> int | None: return self.data["app_extra"] @property - @sensor("Turbo Mode Supported", icon="mdi:rocket") + @sensor("Turbo Mode Supported") def turbo_mode_supported(self) -> bool | None: if self.data["app_extra"] is not None: return self.data["app_extra"] == 1 @@ -354,7 +336,7 @@ def turbo_mode_supported(self) -> bool | None: return None @property - @setting("Auto Detect", setter_name="set_auto_detect", icon="mdi:eye") + @setting("Auto Detect", setter_name="set_auto_detect") def auto_detect(self) -> bool | None: """Return True if auto detect is enabled.""" if self.data["act_det"] is not None: @@ -363,7 +345,7 @@ def auto_detect(self) -> bool | None: return None @property - @sensor("Button Pressed", icon="mdi:gesture-tap-button") + @sensor("Button Pressed") def button_pressed(self) -> str | None: """Last pressed button.""" return self.data["button_pressed"] diff --git a/miio/integrations/zhimi/fan/zhimi_miot.py b/miio/integrations/zhimi/fan/zhimi_miot.py index 3f9da5b70..52c48da1e 100644 --- a/miio/integrations/zhimi/fan/zhimi_miot.py +++ b/miio/integrations/zhimi/fan/zhimi_miot.py @@ -83,19 +83,19 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @setting("Ionizer", setter_name="set_ionizer", icon="mdi:atom") + @setting("Ionizer", setter_name="set_ionizer") def ionizer(self) -> bool: """True if negative ions generation is enabled.""" return self.data["anion"] @property - @sensor("Battery Supported", icon="mdi:battery") + @sensor("Battery Supported") def battery_supported(self) -> bool: """True if battery is supported.""" return self.data["battery_supported"] @property - @sensor("Buttons Pressed", icon="mdi:gesture-tap-button") + @sensor("Buttons Pressed") def buttons_pressed(self) -> str: """What buttons on the fan are pressed now.""" code = self.data["buttons_pressed"] @@ -108,13 +108,13 @@ def buttons_pressed(self) -> str: return "Unknown" @property - @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") + @setting("Buzzer", setter_name="set_buzzer") def buzzer(self) -> bool: """True if buzzer is turned on.""" return self.data["buzzer"] @property - @setting("Child Lock", setter_name="set_child_lock", icon="mdi:lock") + @setting("Child Lock", setter_name="set_child_lock") def child_lock(self) -> bool: """True if child lock if on.""" return self.data["child_lock"] @@ -126,7 +126,6 @@ def child_lock(self) -> bool: min_value=1, max_value=4, step=1, - icon="mdi:fan", ) def fan_level(self) -> int: """Fan level (1-4).""" @@ -146,14 +145,13 @@ def fan_speed(self) -> int: max_value=100, step=1, unit="%", - icon="mdi:fan", ) def speed(self) -> int: """Fan speed (1-100).""" return self.data["fan_speed"] @property - @sensor("Humidity", unit="%", device_class="humidity", icon="mdi:water-percent") + @sensor("Humidity", unit="%", device_class="humidity") def humidity(self) -> int: """Air humidity in percent.""" return self.data["humidity"] @@ -166,26 +164,25 @@ def humidity(self) -> int: max_value=100, step=1, unit="%", - icon="mdi:brightness-6", ) def led_brightness(self) -> int: """LED brightness (1-100).""" return self.data["light"] @property - @setting("Mode", setter_name="set_mode", choices=OperationMode, icon="mdi:fan") + @setting("Mode", setter_name="set_mode", choices=OperationMode) def mode(self) -> OperationMode: """Operation mode (normal or nature).""" return OperationMode[OperationModeFanZA5(self.data["mode"]).name] @property - @sensor("Power", icon="mdi:power") + @sensor("Power") def power(self) -> str: """Power state.""" return "on" if self.data["power"] else "off" @property - @sensor("Is On", icon="mdi:power") + @sensor("Is On") def is_on(self) -> bool: """True if device is currently on.""" return self.data["power"] @@ -195,40 +192,37 @@ def is_on(self) -> bool: "Delay Off Countdown", setter_name="delay_off", unit="s", - icon="mdi:timer-off-outline", ) def delay_off_countdown(self) -> int: """Countdown until turning off in minutes.""" return self.data["power_off_time"] @property - @sensor("Power Supply Attached", icon="mdi:power-plug") + @sensor("Power Supply Attached") def powersupply_attached(self) -> bool: """True is power supply is attached.""" return self.data["powersupply_attached"] @property - @sensor("Speed RPM", unit="rpm", icon="mdi:fan") + @sensor("Speed RPM", unit="rpm") def speed_rpm(self) -> int: """Fan rotations per minute.""" return self.data["speed_rpm"] @property - @setting("Oscillate", setter_name="set_oscillate", icon="mdi:arrow-left-right") + @setting("Oscillate", setter_name="set_oscillate") def oscillate(self) -> bool: """True if oscillation is enabled.""" return self.data["swing_mode"] @property - @setting("Angle", setter_name="set_angle", icon="mdi:angle-acute") + @setting("Angle", setter_name="set_angle") def angle(self) -> int: """Oscillation angle.""" return self.data["swing_mode_angle"] @property - @sensor( - "Temperature", unit="°C", device_class="temperature", icon="mdi:thermometer" - ) + @sensor("Temperature", unit="°C", device_class="temperature") def temperature(self) -> Any: """Air temperature (degree celsius).""" return self.data["temperature"] diff --git a/miio/integrations/zhimi/heater/heater.py b/miio/integrations/zhimi/heater/heater.py index a005d0953..483dfb39c 100644 --- a/miio/integrations/zhimi/heater/heater.py +++ b/miio/integrations/zhimi/heater/heater.py @@ -58,19 +58,19 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @sensor("Power", icon="mdi:power") + @sensor("Power") def power(self) -> str: """Power state.""" return self.data["power"] @property - @sensor("Is On", icon="mdi:power") + @sensor("Is On") def is_on(self) -> bool: """True if device is currently on.""" return self.power == "on" @property - @sensor("Humidity", unit="%", icon="mdi:water-percent", device_class="humidity") + @sensor("Humidity", unit="%", device_class="humidity") def humidity(self) -> int | None: """Current humidity.""" if ( @@ -82,9 +82,7 @@ def humidity(self) -> int | None: return None @property - @sensor( - "Temperature", unit="°C", icon="mdi:thermometer", device_class="temperature" - ) + @sensor("Temperature", unit="°C", device_class="temperature") def temperature(self) -> float: """Current temperature.""" return self.data["temperature"] @@ -97,7 +95,6 @@ def temperature(self) -> float: min_value=16, max_value=32, device_class="temperature", - icon="mdi:thermometer", ) def target_temperature(self) -> int: """Target temperature.""" @@ -108,34 +105,31 @@ def target_temperature(self) -> int: "Brightness", setter_name="set_brightness", choices=Brightness, - icon="mdi:brightness-6", ) def brightness(self) -> Brightness: """Display brightness.""" return Brightness(self.data["brightness"]) @property - @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") + @setting("Buzzer", setter_name="set_buzzer") def buzzer(self) -> bool: """True if buzzer is turned on.""" return self.data["buzzer"] in ["on", 1, 2] @property - @setting("Child Lock", setter_name="set_child_lock", icon="mdi:lock") + @setting("Child Lock", setter_name="set_child_lock") def child_lock(self) -> bool: """True if child lock is on.""" return self.data["child_lock"] == "on" @property - @sensor("Use Time", unit="s", icon="mdi:timer", device_class="duration") + @sensor("Use Time", unit="s", device_class="duration") def use_time(self) -> int: """How long the device has been active in seconds.""" return self.data["use_time"] @property - @sensor( - "Delay Off Countdown", unit="s", icon="mdi:timer-sand", device_class="duration" - ) + @sensor("Delay Off Countdown", unit="s", device_class="duration") def delay_off_countdown(self) -> int | None: """Countdown until turning off in seconds.""" if "poweroff_time" in self.data and self.data["poweroff_time"] is not None: diff --git a/miio/integrations/zhimi/heater/heater_miot.py b/miio/integrations/zhimi/heater/heater_miot.py index 72f630e4b..ba109fd03 100644 --- a/miio/integrations/zhimi/heater/heater_miot.py +++ b/miio/integrations/zhimi/heater/heater_miot.py @@ -122,13 +122,13 @@ def __init__(self, data: dict[str, Any], model: str) -> None: self.model = model @property - @sensor("Power", icon="mdi:power") + @sensor("Power") def power(self) -> str: """Power state.""" return "on" if self.is_on else "off" @property - @sensor("Is On", icon="mdi:power") + @sensor("Is On") def is_on(self) -> bool: """True if device is currently on.""" return self.data["power"] @@ -141,44 +141,37 @@ def is_on(self) -> bool: min_value=18, max_value=28, device_class="temperature", - icon="mdi:thermometer", ) def target_temperature(self) -> int: """Target temperature.""" return self.data["target_temperature"] @property - @sensor( - "Delay Off Countdown", unit="s", icon="mdi:timer-sand", device_class="duration" - ) + @sensor("Delay Off Countdown", unit="s", device_class="duration") def delay_off_countdown(self) -> int: """Countdown until turning off in seconds.""" return self.data["countdown_time"] @property - @sensor( - "Temperature", unit="°C", icon="mdi:thermometer", device_class="temperature" - ) + @sensor("Temperature", unit="°C", device_class="temperature") def temperature(self) -> float: """Current temperature.""" return self.data["temperature"] @property - @sensor( - "Relative Humidity", unit="%", icon="mdi:water-percent", device_class="humidity" - ) + @sensor("Relative Humidity", unit="%", device_class="humidity") def relative_humidity(self) -> int | None: """Current relative humidity.""" return self.data.get("relative_humidity") @property - @setting("Child Lock", setter_name="set_child_lock", icon="mdi:lock") + @setting("Child Lock", setter_name="set_child_lock") def child_lock(self) -> bool: """True if child lock is on, False otherwise.""" return self.data["child_lock"] is True @property - @setting("Buzzer", setter_name="set_buzzer", icon="mdi:volume-high") + @setting("Buzzer", setter_name="set_buzzer") def buzzer(self) -> bool: """True if buzzer is turned on, False otherwise.""" return self.data["buzzer"] is True @@ -188,7 +181,6 @@ def buzzer(self) -> bool: "LED Brightness", setter_name="set_led_brightness", choices=LedBrightness, - icon="mdi:brightness-6", ) def led_brightness(self) -> LedBrightness: """LED indicator brightness.""" diff --git a/miio/integrations/zimi/clock/alarmclock.py b/miio/integrations/zimi/clock/alarmclock.py index 004458ed9..d82d50cc1 100644 --- a/miio/integrations/zimi/clock/alarmclock.py +++ b/miio/integrations/zimi/clock/alarmclock.py @@ -37,17 +37,17 @@ def __init__(self, data): self._end = data[2] @property - @sensor("Enabled", icon="mdi:alarm") + @sensor("Enabled") def enabled(self) -> bool: return self._enabled @property - @sensor("Start Time", icon="mdi:clock-start") + @sensor("Start Time") def start(self) -> str: return self._start @property - @sensor("End Time", icon="mdi:clock-end") + @sensor("End Time") def end(self) -> str: return self._end From 6e47cab65ebb2ff4297109e26eb09902ee9938c6 Mon Sep 17 00:00:00 2001 From: Teemu Rytilahti Date: Sun, 5 Jul 2026 15:50:31 +0200 Subject: [PATCH 5/7] Remove device_class= from @sensor and @setting decorators --- .../airdog/airpurifier/airpurifier_airdog.py | 2 +- miio/integrations/cgllc/airmonitor/airqualitymonitor.py | 8 ++++---- .../cgllc/airmonitor/airqualitymonitor_miot.py | 8 ++++---- miio/integrations/chuangmi/plug/chuangmi_plug.py | 4 ++-- miio/integrations/chunmi/cooker/cooker.py | 2 +- .../integrations/deerma/humidifier/airhumidifier_jsqs.py | 4 ++-- .../deerma/humidifier/airhumidifier_mjjsq.py | 4 ++-- miio/integrations/dmaker/airfresh/airfresh_t2017.py | 5 ++--- miio/integrations/dmaker/fan/fan.py | 2 +- miio/integrations/dreame/vacuum/dreamevacuum_miot.py | 2 +- miio/integrations/huayi/light/huizuo.py | 1 - miio/integrations/ksmb/walkingpad/walkingpad.py | 2 +- miio/integrations/leshow/fan/fan_leshow.py | 1 - .../lumi/acpartner/airconditioningcompanion.py | 4 ++-- .../lumi/acpartner/airconditioningcompanionMCN.py | 3 +-- miio/integrations/lumi/curtain/curtain_youpin.py | 2 +- miio/integrations/mijia/vacuum/g1vacuum.py | 2 +- miio/integrations/nwt/dehumidifier/airdehumidifier.py | 4 ++-- miio/integrations/philips/light/ceil.py | 1 - miio/integrations/philips/light/philips_bulb.py | 1 - miio/integrations/philips/light/philips_eyecare.py | 1 - miio/integrations/philips/light/philips_rwread.py | 1 - miio/integrations/roidmi/vacuum/roidmivacuum_miot.py | 2 +- miio/integrations/shuii/humidifier/airhumidifier_jsq.py | 4 ++-- miio/integrations/tinymu/toiletlid/toiletlid.py | 1 - .../viomi/viomidishwasher/viomidishwasher.py | 2 +- .../xiaomi/aircondition/airconditioner_miot.py | 5 ++--- miio/integrations/xiaomi/wifispeaker/wifispeaker.py | 2 +- .../yeelight/dual_switch/yeelight_dual_switch.py | 2 -- miio/integrations/yunmi/waterpurifier/waterpurifier.py | 2 +- .../yunmi/waterpurifier/waterpurifier_yunmi.py | 2 +- miio/integrations/zhimi/airpurifier/airfresh.py | 8 ++++---- miio/integrations/zhimi/airpurifier/airpurifier.py | 6 +++--- miio/integrations/zhimi/fan/zhimi_miot.py | 4 ++-- miio/integrations/zhimi/heater/heater.py | 9 ++++----- miio/integrations/zhimi/heater/heater_miot.py | 7 +++---- 36 files changed, 53 insertions(+), 67 deletions(-) diff --git a/miio/integrations/airdog/airpurifier/airpurifier_airdog.py b/miio/integrations/airdog/airpurifier/airpurifier_airdog.py index a4180276b..cad28bc47 100644 --- a/miio/integrations/airdog/airpurifier/airpurifier_airdog.py +++ b/miio/integrations/airdog/airpurifier/airpurifier_airdog.py @@ -98,7 +98,7 @@ def clean_filters(self) -> bool: return self.data["clean"] == "y" @property - @sensor("PM2.5", unit="μg/m³", device_class="pm25") + @sensor("PM2.5", unit="μg/m³") def pm25(self) -> int: """Return particulate matter value (0...300μg/m³).""" return self.data["pm"] diff --git a/miio/integrations/cgllc/airmonitor/airqualitymonitor.py b/miio/integrations/cgllc/airmonitor/airqualitymonitor.py index 1cc8ca81f..a0c48ca13 100644 --- a/miio/integrations/cgllc/airmonitor/airqualitymonitor.py +++ b/miio/integrations/cgllc/airmonitor/airqualitymonitor.py @@ -84,7 +84,7 @@ def aqi(self) -> int | None: return self.data.get("aqi") @property - @sensor("Battery", unit="%", device_class="battery") + @sensor("Battery", unit="%") def battery(self) -> int | None: """Current battery level (0..100).""" return self.data.get("battery") @@ -134,19 +134,19 @@ def co2e(self) -> int | None: return self.data.get("co2e") @property - @sensor("Humidity", unit="%", device_class="humidity") + @sensor("Humidity", unit="%") def humidity(self) -> float | None: """Return humidity value (0...100%).""" return self.data.get("humidity") @property - @sensor("PM2.5", unit="μg/m³", device_class="pm25") + @sensor("PM2.5", unit="μg/m³") def pm25(self) -> float | None: """Return pm2.5 value (0...999μg/m³).""" return self.data.get("pm25") @property - @sensor("Temperature", unit="°C", device_class="temperature") + @sensor("Temperature", unit="°C") def temperature(self) -> float | None: """Return temperature value (-10...50°C).""" return self.data.get("temperature") diff --git a/miio/integrations/cgllc/airmonitor/airqualitymonitor_miot.py b/miio/integrations/cgllc/airmonitor/airqualitymonitor_miot.py index 682a087d6..24da44e7e 100644 --- a/miio/integrations/cgllc/airmonitor/airqualitymonitor_miot.py +++ b/miio/integrations/cgllc/airmonitor/airqualitymonitor_miot.py @@ -108,7 +108,7 @@ def __init__(self, data): self.data = data @property - @sensor("Humidity", unit="%", device_class="humidity") + @sensor("Humidity", unit="%") def humidity(self) -> int: """Return humidity value (0...100%).""" return self.data["humidity"] @@ -126,19 +126,19 @@ def pm10(self) -> int: return self.data["pm10"] @property - @sensor("Temperature", unit="°C", device_class="temperature") + @sensor("Temperature", unit="°C") def temperature(self) -> float: """Return temperature value (-30...100°C).""" return self.data["temperature"] @property - @sensor("CO2", unit="ppm", device_class="carbon_dioxide") + @sensor("CO2", unit="ppm") def co2(self) -> int: """Return co2 value (0...9999ppm).""" return self.data["co2"] @property - @sensor("Battery", unit="%", device_class="battery") + @sensor("Battery", unit="%") def battery(self) -> int: """Return battery level (0...100%).""" return self.data["battery"] diff --git a/miio/integrations/chuangmi/plug/chuangmi_plug.py b/miio/integrations/chuangmi/plug/chuangmi_plug.py index bc21ba27e..fb412d0e1 100644 --- a/miio/integrations/chuangmi/plug/chuangmi_plug.py +++ b/miio/integrations/chuangmi/plug/chuangmi_plug.py @@ -63,7 +63,7 @@ def is_on(self) -> bool: return self.power @property - @sensor("Temperature", unit="°C", device_class="temperature") + @sensor("Temperature", unit="°C") def temperature(self) -> int: return self.data["temperature"] @@ -76,7 +76,7 @@ def usb_power(self) -> bool | None: return None @property - @sensor("Load Power", unit="W", device_class="power") + @sensor("Load Power", unit="W") def load_power(self) -> float | None: """Current power load, if available.""" if "load_power" in self.data and self.data["load_power"] is not None: diff --git a/miio/integrations/chunmi/cooker/cooker.py b/miio/integrations/chunmi/cooker/cooker.py index 173ed5543..189667af2 100644 --- a/miio/integrations/chunmi/cooker/cooker.py +++ b/miio/integrations/chunmi/cooker/cooker.py @@ -520,7 +520,7 @@ def stage(self) -> CookingStage | None: return None @property - @sensor("Temperature", unit="°C", device_class="temperature") + @sensor("Temperature", unit="°C") def temperature(self) -> int | None: """Current temperature, if idle. diff --git a/miio/integrations/deerma/humidifier/airhumidifier_jsqs.py b/miio/integrations/deerma/humidifier/airhumidifier_jsqs.py index 4ed660205..8c80b5302 100644 --- a/miio/integrations/deerma/humidifier/airhumidifier_jsqs.py +++ b/miio/integrations/deerma/humidifier/airhumidifier_jsqs.py @@ -112,13 +112,13 @@ def target_humidity(self) -> int | None: # Environment @property - @sensor(name="Relative Humidity", unit="%", device_class="humidity") + @sensor(name="Relative Humidity", unit="%") def relative_humidity(self) -> int | None: """Return current humidity.""" return self.data.get("relative_humidity") @property - @sensor(name="Temperature", unit="C", device_class="temperature") + @sensor(name="Temperature", unit="C") def temperature(self) -> float | None: """Return current temperature, if available.""" return self.data.get("temperature") diff --git a/miio/integrations/deerma/humidifier/airhumidifier_mjjsq.py b/miio/integrations/deerma/humidifier/airhumidifier_mjjsq.py index adef09017..0e055e5c3 100644 --- a/miio/integrations/deerma/humidifier/airhumidifier_mjjsq.py +++ b/miio/integrations/deerma/humidifier/airhumidifier_mjjsq.py @@ -81,13 +81,13 @@ def mode(self) -> OperationMode: return OperationMode(self.data["Humidifier_Gear"]) @property - @sensor(name="Temperature", unit="C", device_class="temperature") + @sensor(name="Temperature", unit="C") def temperature(self) -> int: """Current temperature in degree celsius.""" return self.data["TemperatureValue"] @property - @sensor(name="Humidity", unit="%", device_class="humidity") + @sensor(name="Humidity", unit="%") def humidity(self) -> int: """Current humidity in percent.""" return self.data["Humidity_Value"] diff --git a/miio/integrations/dmaker/airfresh/airfresh_t2017.py b/miio/integrations/dmaker/airfresh/airfresh_t2017.py index 16a9158e0..87101cd98 100644 --- a/miio/integrations/dmaker/airfresh/airfresh_t2017.py +++ b/miio/integrations/dmaker/airfresh/airfresh_t2017.py @@ -134,7 +134,7 @@ def mode(self) -> OperationMode: return OperationMode(self.data["mode"]) @property - @sensor("PM2.5", unit="μg/m³", device_class="pm25") + @sensor("PM2.5", unit="μg/m³") def pm25(self) -> int: """Fine particulate patter (PM2.5).""" return self.data["pm25"] @@ -143,14 +143,13 @@ def pm25(self) -> int: @sensor( "CO2", unit="ppm", - device_class="carbon_dioxide", ) def co2(self) -> int: """Carbon dioxide.""" return self.data["co2"] @property - @sensor("Temperature", unit="°C", device_class="temperature") + @sensor("Temperature", unit="°C") def temperature(self) -> int: """Current temperature in degree celsions.""" return self.data["temperature_outside"] diff --git a/miio/integrations/dmaker/fan/fan.py b/miio/integrations/dmaker/fan/fan.py index 3543923a2..a33f45cbc 100644 --- a/miio/integrations/dmaker/fan/fan.py +++ b/miio/integrations/dmaker/fan/fan.py @@ -102,7 +102,7 @@ def angle(self) -> int: return self.data["roll_angle"] @property - @sensor("Delay Off Countdown", unit="s", device_class="duration") + @sensor("Delay Off Countdown", unit="s") def delay_off_countdown(self) -> int: """Countdown until turning off in seconds.""" return self.data["time_off"] diff --git a/miio/integrations/dreame/vacuum/dreamevacuum_miot.py b/miio/integrations/dreame/vacuum/dreamevacuum_miot.py index 78fb2c8d2..a098c76a2 100644 --- a/miio/integrations/dreame/vacuum/dreamevacuum_miot.py +++ b/miio/integrations/dreame/vacuum/dreamevacuum_miot.py @@ -306,7 +306,7 @@ def __init__(self, data, model): self.model = model @property - @sensor("Battery Level", unit="%", device_class="battery") + @sensor("Battery Level", unit="%") def battery_level(self) -> str: return self.data["battery_level"] diff --git a/miio/integrations/huayi/light/huizuo.py b/miio/integrations/huayi/light/huizuo.py index 4374fa53d..951ac84cf 100644 --- a/miio/integrations/huayi/light/huizuo.py +++ b/miio/integrations/huayi/light/huizuo.py @@ -142,7 +142,6 @@ def brightness(self) -> int: setter_name="set_color_temp", min_value=3000, max_value=6400, - device_class="temperature", ) def color_temp(self) -> int: """Return current color temperature.""" diff --git a/miio/integrations/ksmb/walkingpad/walkingpad.py b/miio/integrations/ksmb/walkingpad/walkingpad.py index 9aed4e4be..f14005365 100644 --- a/miio/integrations/ksmb/walkingpad/walkingpad.py +++ b/miio/integrations/ksmb/walkingpad/walkingpad.py @@ -56,7 +56,7 @@ def is_on(self) -> bool: return self.power == "on" @property - @sensor("Walking Time", device_class="duration") + @sensor("Walking Time") def walking_time(self) -> timedelta: """Current walking duration in seconds.""" return timedelta(seconds=int(self.data["time"])) diff --git a/miio/integrations/leshow/fan/fan_leshow.py b/miio/integrations/leshow/fan/fan_leshow.py index ea0a1f536..f734c4a49 100644 --- a/miio/integrations/leshow/fan/fan_leshow.py +++ b/miio/integrations/leshow/fan/fan_leshow.py @@ -96,7 +96,6 @@ def oscillate(self) -> bool: @setting( "Delay Off Countdown", setter_name="delay_off", - device_class="duration", unit="min", min_value=0, max_value=540, diff --git a/miio/integrations/lumi/acpartner/airconditioningcompanion.py b/miio/integrations/lumi/acpartner/airconditioningcompanion.py index 0147a0adf..25952fb9d 100644 --- a/miio/integrations/lumi/acpartner/airconditioningcompanion.py +++ b/miio/integrations/lumi/acpartner/airconditioningcompanion.py @@ -98,7 +98,7 @@ def __init__(self, data): self.state = data["model_and_state"][1] @property - @sensor("Load Power", unit="W", device_class="power") + @sensor("Load Power", unit="W") def load_power(self) -> int: """Current power load of the air conditioner.""" return int(self.data["model_and_state"][2]) @@ -196,7 +196,7 @@ def is_on(self) -> bool: return self.power == "on" @property - @sensor("Target Temperature", unit="°C", device_class="temperature") + @sensor("Target Temperature", unit="°C") def target_temperature(self) -> int | None: """Target temperature.""" try: diff --git a/miio/integrations/lumi/acpartner/airconditioningcompanionMCN.py b/miio/integrations/lumi/acpartner/airconditioningcompanionMCN.py index e815fee5c..8b270485b 100644 --- a/miio/integrations/lumi/acpartner/airconditioningcompanionMCN.py +++ b/miio/integrations/lumi/acpartner/airconditioningcompanionMCN.py @@ -45,7 +45,7 @@ def __init__(self, data): self.data = data @property - @sensor("Load Power", unit="W", device_class="power") + @sensor("Load Power", unit="W") def load_power(self) -> int: """Current power load of the air conditioner.""" return int(self.data[-1]) @@ -77,7 +77,6 @@ def mode(self) -> OperationMode | None: "Target Temperature", setter_name="send_command", unit="°C", - device_class="temperature", ) def target_temperature(self) -> int | None: """Target temperature.""" diff --git a/miio/integrations/lumi/curtain/curtain_youpin.py b/miio/integrations/lumi/curtain/curtain_youpin.py index 49af25e83..e2cfb7d89 100644 --- a/miio/integrations/lumi/curtain/curtain_youpin.py +++ b/miio/integrations/lumi/curtain/curtain_youpin.py @@ -111,7 +111,7 @@ def night_tip_light(self) -> bool: return bool(self.data["night_tip_light"]) @property - @sensor("Run Time", device_class="duration", unit="s") + @sensor("Run Time", unit="s") def run_time(self) -> int: """Run time of the motor.""" return self.data["run_time"] diff --git a/miio/integrations/mijia/vacuum/g1vacuum.py b/miio/integrations/mijia/vacuum/g1vacuum.py index 60a0227ee..e08985c51 100644 --- a/miio/integrations/mijia/vacuum/g1vacuum.py +++ b/miio/integrations/mijia/vacuum/g1vacuum.py @@ -160,7 +160,7 @@ def __init__(self, data): self.data = data @property - @sensor("Battery", unit="%", device_class="battery") + @sensor("Battery", unit="%") def battery(self) -> int: """Battery Level.""" return self.data["battery"] diff --git a/miio/integrations/nwt/dehumidifier/airdehumidifier.py b/miio/integrations/nwt/dehumidifier/airdehumidifier.py index 132e150ce..c63d0b04d 100644 --- a/miio/integrations/nwt/dehumidifier/airdehumidifier.py +++ b/miio/integrations/nwt/dehumidifier/airdehumidifier.py @@ -89,7 +89,7 @@ def mode(self) -> OperationMode: return OperationMode(self.data["mode"]) @property - @sensor("Temperature", unit="°C", device_class="temperature") + @sensor("Temperature", unit="°C") def temperature(self) -> float | None: """Current temperature, if available.""" if "temp" in self.data and self.data["temp"] is not None: @@ -97,7 +97,7 @@ def temperature(self) -> float | None: return None @property - @sensor("Humidity", unit="%", device_class="humidity") + @sensor("Humidity", unit="%") def humidity(self) -> int: """Current humidity.""" return self.data["humidity"] diff --git a/miio/integrations/philips/light/ceil.py b/miio/integrations/philips/light/ceil.py index 46fda9abf..a808aa365 100644 --- a/miio/integrations/philips/light/ceil.py +++ b/miio/integrations/philips/light/ceil.py @@ -66,7 +66,6 @@ def scene(self) -> int: @setting( "Delay Off Countdown", setter_name="delay_off", - device_class="duration", unit="s", ) def delay_off_countdown(self) -> int: diff --git a/miio/integrations/philips/light/philips_bulb.py b/miio/integrations/philips/light/philips_bulb.py index c7658e108..4ffdd89f0 100644 --- a/miio/integrations/philips/light/philips_bulb.py +++ b/miio/integrations/philips/light/philips_bulb.py @@ -74,7 +74,6 @@ def scene(self) -> int | None: @sensor( "Delay Off Countdown", unit="s", - device_class="duration", ) def delay_off_countdown(self) -> int: return self.data["dv"] diff --git a/miio/integrations/philips/light/philips_eyecare.py b/miio/integrations/philips/light/philips_eyecare.py index 33d066393..fe188190b 100644 --- a/miio/integrations/philips/light/philips_eyecare.py +++ b/miio/integrations/philips/light/philips_eyecare.py @@ -98,7 +98,6 @@ def smart_night_light(self) -> bool: @sensor( "Delay Off Countdown", unit="min", - device_class="duration", ) def delay_off_countdown(self) -> int: """Countdown until turning off in minutes.""" diff --git a/miio/integrations/philips/light/philips_rwread.py b/miio/integrations/philips/light/philips_rwread.py index 6df10bddb..d6ad392d9 100644 --- a/miio/integrations/philips/light/philips_rwread.py +++ b/miio/integrations/philips/light/philips_rwread.py @@ -64,7 +64,6 @@ def brightness(self) -> int: @setting( "Delay Off Countdown", setter_name="delay_off", - device_class="duration", unit="s", ) def delay_off_countdown(self) -> int: diff --git a/miio/integrations/roidmi/vacuum/roidmivacuum_miot.py b/miio/integrations/roidmi/vacuum/roidmivacuum_miot.py index 1127b5867..2b77be345 100644 --- a/miio/integrations/roidmi/vacuum/roidmivacuum_miot.py +++ b/miio/integrations/roidmi/vacuum/roidmivacuum_miot.py @@ -225,7 +225,7 @@ def __init__(self, data): self.data = data @property - @sensor("Battery", unit="%", device_class="battery") + @sensor("Battery", unit="%") def battery(self) -> int: """Remaining battery in percentage.""" return self.data["battery_level"] diff --git a/miio/integrations/shuii/humidifier/airhumidifier_jsq.py b/miio/integrations/shuii/humidifier/airhumidifier_jsq.py index 0c4e61a86..e323c714b 100644 --- a/miio/integrations/shuii/humidifier/airhumidifier_jsq.py +++ b/miio/integrations/shuii/humidifier/airhumidifier_jsq.py @@ -92,13 +92,13 @@ def mode(self) -> OperationMode: return mode @property - @sensor(name="Temperature", unit="C", device_class="temperature") + @sensor(name="Temperature", unit="C") def temperature(self) -> int: """Current temperature in degree celsius.""" return self.data["temperature"] @property - @sensor(name="Humidity", unit="%", device_class="humidity") + @sensor(name="Humidity", unit="%") def humidity(self) -> int: """Current humidity in percent.""" return self.data["humidity"] diff --git a/miio/integrations/tinymu/toiletlid/toiletlid.py b/miio/integrations/tinymu/toiletlid/toiletlid.py index e657e2be6..f47dc7246 100644 --- a/miio/integrations/tinymu/toiletlid/toiletlid.py +++ b/miio/integrations/tinymu/toiletlid/toiletlid.py @@ -68,7 +68,6 @@ def filter_use_percentage(self) -> str: @sensor( "Filter Remaining Time", unit="d", - device_class="duration", ) def filter_remaining_time(self) -> int: """Filter remaining life days.""" diff --git a/miio/integrations/viomi/viomidishwasher/viomidishwasher.py b/miio/integrations/viomi/viomidishwasher/viomidishwasher.py index ae6ac3968..5fabb2e88 100644 --- a/miio/integrations/viomi/viomidishwasher/viomidishwasher.py +++ b/miio/integrations/viomi/viomidishwasher/viomidishwasher.py @@ -155,7 +155,7 @@ def status(self) -> MachineStatus: return MachineStatus(self.data["wash_status"]) @property - @sensor(name="Temperature", unit="C", device_class="temperature") + @sensor(name="Temperature", unit="C") def temperature(self) -> int: """Returns the temperature in degree Celsius as determined by the NTC thermistor.""" diff --git a/miio/integrations/xiaomi/aircondition/airconditioner_miot.py b/miio/integrations/xiaomi/aircondition/airconditioner_miot.py index 25d025756..5ee23f16b 100644 --- a/miio/integrations/xiaomi/aircondition/airconditioner_miot.py +++ b/miio/integrations/xiaomi/aircondition/airconditioner_miot.py @@ -224,7 +224,6 @@ def mode(self) -> OperationMode: min_value=16, max_value=31, step=1, - device_class="temperature", ) def target_temperature(self) -> float: """Target temperature in Celsius.""" @@ -267,7 +266,7 @@ def vertical_swing(self) -> bool: return self.data["vertical_swing"] @property - @sensor("Temperature", unit="°C", device_class="temperature") + @sensor("Temperature", unit="°C") def temperature(self) -> float: """Current ambient temperature in Celsius.""" return self.data["temperature"] @@ -285,7 +284,7 @@ def led(self) -> bool: return self.data["led"] @property - @sensor("Electricity", unit="kWh", device_class="energy") + @sensor("Electricity", unit="kWh") def electricity(self) -> float: """Power consumption accumulation in kWh.""" return self.data["electricity"] diff --git a/miio/integrations/xiaomi/wifispeaker/wifispeaker.py b/miio/integrations/xiaomi/wifispeaker/wifispeaker.py index 13a633a3b..ee3c32bc5 100644 --- a/miio/integrations/xiaomi/wifispeaker/wifispeaker.py +++ b/miio/integrations/xiaomi/wifispeaker/wifispeaker.py @@ -90,7 +90,7 @@ def track_title(self) -> str: return self.data["track_title"] @property - @sensor("Track Duration", device_class="duration") + @sensor("Track Duration") def track_duration(self) -> str: """Total duration of the current track.""" return self.data["track_duration"] diff --git a/miio/integrations/yeelight/dual_switch/yeelight_dual_switch.py b/miio/integrations/yeelight/dual_switch/yeelight_dual_switch.py index 70ce6a664..07cac2af1 100644 --- a/miio/integrations/yeelight/dual_switch/yeelight_dual_switch.py +++ b/miio/integrations/yeelight/dual_switch/yeelight_dual_switch.py @@ -80,7 +80,6 @@ def switch_1_default_state(self) -> bool: @setting( "Switch 1 Off Delay", setter_name="set_switch_off_delay", - device_class="duration", unit="s", min_value=-1, max_value=43200, @@ -109,7 +108,6 @@ def switch_2_default_state(self) -> bool: @setting( "Switch 2 Off Delay", setter_name="set_switch_off_delay", - device_class="duration", unit="s", min_value=-1, max_value=43200, diff --git a/miio/integrations/yunmi/waterpurifier/waterpurifier.py b/miio/integrations/yunmi/waterpurifier/waterpurifier.py index 4e5640bc2..3782e9d84 100644 --- a/miio/integrations/yunmi/waterpurifier/waterpurifier.py +++ b/miio/integrations/yunmi/waterpurifier/waterpurifier.py @@ -88,7 +88,7 @@ def usage(self) -> str: return self.data["usage"] @property - @sensor("Temperature", unit="°C", device_class="temperature") + @sensor("Temperature", unit="°C") def temperature(self) -> str: return self.data["temperature"] diff --git a/miio/integrations/yunmi/waterpurifier/waterpurifier_yunmi.py b/miio/integrations/yunmi/waterpurifier/waterpurifier_yunmi.py index e3a178335..da314eeb8 100644 --- a/miio/integrations/yunmi/waterpurifier/waterpurifier_yunmi.py +++ b/miio/integrations/yunmi/waterpurifier/waterpurifier_yunmi.py @@ -253,7 +253,7 @@ def rinse(self) -> bool: return self.data["rinse"] @property - @sensor("Temperature", unit="°C", device_class="temperature") + @sensor("Temperature", unit="°C") def temperature(self) -> int: """Current water temperature in Celsius.""" return self.data["temperature"] diff --git a/miio/integrations/zhimi/airpurifier/airfresh.py b/miio/integrations/zhimi/airpurifier/airfresh.py index 6f63ff519..409a9a99b 100644 --- a/miio/integrations/zhimi/airpurifier/airfresh.py +++ b/miio/integrations/zhimi/airpurifier/airfresh.py @@ -117,13 +117,13 @@ def average_aqi(self) -> int: return self.data["average_aqi"] @property - @sensor("CO2", unit="ppm", device_class="carbon_dioxide") + @sensor("CO2", unit="ppm") def co2(self) -> int: """Carbon dioxide.""" return self.data["co2"] @property - @sensor("Humidity", unit="%", device_class="humidity") + @sensor("Humidity", unit="%") def humidity(self) -> int: """Current humidity.""" return self.data["humidity"] @@ -138,7 +138,7 @@ def ptc(self) -> bool | None: return None @property - @sensor("Temperature", unit="°C", device_class="temperature") + @sensor("Temperature", unit="°C") def temperature(self) -> float | None: """Current temperature, if available.""" if self.data["temp_dec"] is not None: @@ -150,7 +150,7 @@ def temperature(self) -> float | None: return None @property - @sensor("NTC Temperature", unit="°C", device_class="temperature") + @sensor("NTC Temperature", unit="°C") def ntc_temperature(self) -> float | None: """Current ntc temperature, if available.""" if self.data["ntcT"] is not None: diff --git a/miio/integrations/zhimi/airpurifier/airpurifier.py b/miio/integrations/zhimi/airpurifier/airpurifier.py index 4de1313ff..d6c8c6767 100644 --- a/miio/integrations/zhimi/airpurifier/airpurifier.py +++ b/miio/integrations/zhimi/airpurifier/airpurifier.py @@ -155,13 +155,13 @@ def average_aqi(self) -> int: return self.data["average_aqi"] @property - @sensor("Humidity", unit="%", device_class="humidity") + @sensor("Humidity", unit="%") def humidity(self) -> int: """Current humidity.""" return self.data["humidity"] @property - @sensor("Temperature", unit="°C", device_class="temperature") + @sensor("Temperature", unit="°C") def temperature(self) -> float | None: """Current temperature, if available.""" if self.data["temp_dec"] is not None: @@ -206,7 +206,7 @@ def led_brightness(self) -> LedBrightness | None: return None @property - @sensor("Illuminance", unit="lx", device_class="illuminance") + @sensor("Illuminance", unit="lx") def illuminance(self) -> int | None: """Environment illuminance level in lux [0-200]. diff --git a/miio/integrations/zhimi/fan/zhimi_miot.py b/miio/integrations/zhimi/fan/zhimi_miot.py index 52c48da1e..df7d6248c 100644 --- a/miio/integrations/zhimi/fan/zhimi_miot.py +++ b/miio/integrations/zhimi/fan/zhimi_miot.py @@ -151,7 +151,7 @@ def speed(self) -> int: return self.data["fan_speed"] @property - @sensor("Humidity", unit="%", device_class="humidity") + @sensor("Humidity", unit="%") def humidity(self) -> int: """Air humidity in percent.""" return self.data["humidity"] @@ -222,7 +222,7 @@ def angle(self) -> int: return self.data["swing_mode_angle"] @property - @sensor("Temperature", unit="°C", device_class="temperature") + @sensor("Temperature", unit="°C") def temperature(self) -> Any: """Air temperature (degree celsius).""" return self.data["temperature"] diff --git a/miio/integrations/zhimi/heater/heater.py b/miio/integrations/zhimi/heater/heater.py index 483dfb39c..30b9fc4a9 100644 --- a/miio/integrations/zhimi/heater/heater.py +++ b/miio/integrations/zhimi/heater/heater.py @@ -70,7 +70,7 @@ def is_on(self) -> bool: return self.power == "on" @property - @sensor("Humidity", unit="%", device_class="humidity") + @sensor("Humidity", unit="%") def humidity(self) -> int | None: """Current humidity.""" if ( @@ -82,7 +82,7 @@ def humidity(self) -> int | None: return None @property - @sensor("Temperature", unit="°C", device_class="temperature") + @sensor("Temperature", unit="°C") def temperature(self) -> float: """Current temperature.""" return self.data["temperature"] @@ -94,7 +94,6 @@ def temperature(self) -> float: setter_name="set_target_temperature", min_value=16, max_value=32, - device_class="temperature", ) def target_temperature(self) -> int: """Target temperature.""" @@ -123,13 +122,13 @@ def child_lock(self) -> bool: return self.data["child_lock"] == "on" @property - @sensor("Use Time", unit="s", device_class="duration") + @sensor("Use Time", unit="s") def use_time(self) -> int: """How long the device has been active in seconds.""" return self.data["use_time"] @property - @sensor("Delay Off Countdown", unit="s", device_class="duration") + @sensor("Delay Off Countdown", unit="s") def delay_off_countdown(self) -> int | None: """Countdown until turning off in seconds.""" if "poweroff_time" in self.data and self.data["poweroff_time"] is not None: diff --git a/miio/integrations/zhimi/heater/heater_miot.py b/miio/integrations/zhimi/heater/heater_miot.py index ba109fd03..e9b2ea089 100644 --- a/miio/integrations/zhimi/heater/heater_miot.py +++ b/miio/integrations/zhimi/heater/heater_miot.py @@ -140,26 +140,25 @@ def is_on(self) -> bool: setter_name="set_target_temperature", min_value=18, max_value=28, - device_class="temperature", ) def target_temperature(self) -> int: """Target temperature.""" return self.data["target_temperature"] @property - @sensor("Delay Off Countdown", unit="s", device_class="duration") + @sensor("Delay Off Countdown", unit="s") def delay_off_countdown(self) -> int: """Countdown until turning off in seconds.""" return self.data["countdown_time"] @property - @sensor("Temperature", unit="°C", device_class="temperature") + @sensor("Temperature", unit="°C") def temperature(self) -> float: """Current temperature.""" return self.data["temperature"] @property - @sensor("Relative Humidity", unit="%", device_class="humidity") + @sensor("Relative Humidity", unit="%") def relative_humidity(self) -> int | None: """Current relative humidity.""" return self.data.get("relative_humidity") From 4292b89c5e6c6fe80bdc3917f88299e7d6fe518f Mon Sep 17 00:00:00 2001 From: Teemu Rytilahti Date: Sun, 5 Jul 2026 16:00:04 +0200 Subject: [PATCH 6/7] Remove @setting decorators with one-way on/off setters --- miio/integrations/chuangmi/camera/chuangmi_camera.py | 10 +--------- miio/integrations/chuangmi/plug/chuangmi_plug.py | 2 -- .../deerma/humidifier/airhumidifier_jsqs.py | 1 - .../deerma/humidifier/airhumidifier_mjjsq.py | 1 - .../lumi/acpartner/airconditioningcompanionMCN.py | 1 - miio/integrations/lumi/camera/aqaracamera.py | 5 ----- miio/integrations/mmgg/petwaterdispenser/status.py | 1 - miio/integrations/philips/light/philips_bulb.py | 1 - miio/integrations/philips/light/philips_eyecare.py | 7 ------- miio/integrations/philips/light/philips_moonlight.py | 1 - .../integrations/shuii/humidifier/airhumidifier_jsq.py | 1 - .../viomi/viomidishwasher/viomidishwasher.py | 1 - 12 files changed, 1 insertion(+), 31 deletions(-) diff --git a/miio/integrations/chuangmi/camera/chuangmi_camera.py b/miio/integrations/chuangmi/camera/chuangmi_camera.py index ae61c272b..39dd402da 100644 --- a/miio/integrations/chuangmi/camera/chuangmi_camera.py +++ b/miio/integrations/chuangmi/camera/chuangmi_camera.py @@ -11,7 +11,7 @@ from miio.click_common import EnumType, command, format_output from miio.device import Device, DeviceStatus -from miio.devicestatus import sensor, setting +from miio.devicestatus import sensor _LOGGER = logging.getLogger(__name__) @@ -92,43 +92,36 @@ def __init__(self, data: dict[str, Any]) -> None: self.data = data @property - @setting(name="Power", setter_name="on") def power(self) -> bool: """Camera power.""" return self.data["power"] == "on" @property - @setting(name="Motion Record", setter_name="motion_record_on") def motion_record(self) -> bool: """Motion record status.""" return self.data["motion_record"] == "on" @property - @setting(name="Light", setter_name="light_on") def light(self) -> bool: """Camera light status.""" return self.data["light"] == "on" @property - @setting(name="Full Color", setter_name="full_color_on") def full_color(self) -> bool: """Full color with bad lighting conditions.""" return self.data["full_color"] == "on" @property - @setting(name="Flip", setter_name="flip_on") def flip(self) -> bool: """Image 180 degrees flip status.""" return self.data["flip"] == "on" @property - @setting(name="Improve Program", setter_name="improve_program_on") def improve_program(self) -> bool: """Customer experience improvement program status.""" return self.data["improve_program"] == "on" @property - @setting(name="WDR", setter_name="wdr_on") def wdr(self) -> bool: """Wide dynamic range status.""" return self.data["wdr"] == "on" @@ -140,7 +133,6 @@ def track(self) -> bool: return self.data["track"] == "on" @property - @setting(name="Watermark", setter_name="watermark_on") def watermark(self) -> bool: """Apply watermark to video.""" return self.data["watermark"] == "on" diff --git a/miio/integrations/chuangmi/plug/chuangmi_plug.py b/miio/integrations/chuangmi/plug/chuangmi_plug.py index fb412d0e1..c0d448bd8 100644 --- a/miio/integrations/chuangmi/plug/chuangmi_plug.py +++ b/miio/integrations/chuangmi/plug/chuangmi_plug.py @@ -57,7 +57,6 @@ def power(self) -> bool: raise DeviceException("There was neither 'on' or 'power' in data") @property - @setting("Power", setter_name="on") def is_on(self) -> bool: """True if device is on.""" return self.power @@ -68,7 +67,6 @@ def temperature(self) -> int: return self.data["temperature"] @property - @setting("USB Power", setter_name="usb_on") def usb_power(self) -> bool | None: """True if USB is on.""" if "usb_on" in self.data and self.data["usb_on"] is not None: diff --git a/miio/integrations/deerma/humidifier/airhumidifier_jsqs.py b/miio/integrations/deerma/humidifier/airhumidifier_jsqs.py index 8c80b5302..6af103eee 100644 --- a/miio/integrations/deerma/humidifier/airhumidifier_jsqs.py +++ b/miio/integrations/deerma/humidifier/airhumidifier_jsqs.py @@ -70,7 +70,6 @@ def __init__(self, data: dict[str, Any]) -> None: # Air Humidifier @property - @setting(name="Power", setter_name="on") def is_on(self) -> bool: """Return True if device is on.""" return self.data["power"] diff --git a/miio/integrations/deerma/humidifier/airhumidifier_mjjsq.py b/miio/integrations/deerma/humidifier/airhumidifier_mjjsq.py index 0e055e5c3..8be9c010f 100644 --- a/miio/integrations/deerma/humidifier/airhumidifier_mjjsq.py +++ b/miio/integrations/deerma/humidifier/airhumidifier_mjjsq.py @@ -62,7 +62,6 @@ def power(self) -> str: return "on" if self.data["OnOff_State"] == 1 else "off" @property - @setting(name="Power", setter_name="on") def is_on(self) -> bool: """True if device is turned on.""" return self.power == "on" diff --git a/miio/integrations/lumi/acpartner/airconditioningcompanionMCN.py b/miio/integrations/lumi/acpartner/airconditioningcompanionMCN.py index 8b270485b..fd8d2dcd6 100644 --- a/miio/integrations/lumi/acpartner/airconditioningcompanionMCN.py +++ b/miio/integrations/lumi/acpartner/airconditioningcompanionMCN.py @@ -57,7 +57,6 @@ def power(self) -> str: return self.data[0] @property - @setting("Power", setter_name="on") def is_on(self) -> bool: """True if the device is turned on.""" return self.power == "on" diff --git a/miio/integrations/lumi/camera/aqaracamera.py b/miio/integrations/lumi/camera/aqaracamera.py index 120bb7b00..04c63ba30 100644 --- a/miio/integrations/lumi/camera/aqaracamera.py +++ b/miio/integrations/lumi/camera/aqaracamera.py @@ -94,7 +94,6 @@ def is_on(self) -> bool: return self.video_status == 1 @property - @setting("Motion Detection", setter_name="md_on") def md(self) -> bool: """Motion detection state.""" return bool(self.data["md_status"]) @@ -109,19 +108,16 @@ def md_sensitivity(self): return self.data["mdsensitivity"] @property - @setting("IR Mode", setter_name="ir_on") def ir(self): """IR mode.""" return bool(self.data["ir_status"]) @property - @setting("LED", setter_name="led_on") def led(self): """LED status.""" return bool(self.data["led_status"]) @property - @setting("Flipped", setter_name="flip_on") def flipped(self) -> bool: """TODO: If camera is flipped?""" return self.data["flip_state"] @@ -143,7 +139,6 @@ def channel_id(self) -> int: return self.data["channel_id"] @property - @setting("Fullstop", setter_name="fullstop_on") def fullstop(self) -> bool: """Is alarm triggered by MD.""" return self.data["fullstop"] != 0 diff --git a/miio/integrations/mmgg/petwaterdispenser/status.py b/miio/integrations/mmgg/petwaterdispenser/status.py index 78cd44fde..ac90c6d72 100644 --- a/miio/integrations/mmgg/petwaterdispenser/status.py +++ b/miio/integrations/mmgg/petwaterdispenser/status.py @@ -41,7 +41,6 @@ def sponge_filter_left_days(self) -> timedelta: return timedelta(days=self.data["filter_left_time"]) @property - @setting(name="Power", setter_name="on") def is_on(self) -> bool: """True if device is on.""" return self.data["on"] diff --git a/miio/integrations/philips/light/philips_bulb.py b/miio/integrations/philips/light/philips_bulb.py index 4ffdd89f0..3c45ea46b 100644 --- a/miio/integrations/philips/light/philips_bulb.py +++ b/miio/integrations/philips/light/philips_bulb.py @@ -43,7 +43,6 @@ def power(self) -> str: return self.data["power"] @property - @setting("Power", setter_name="on") def is_on(self) -> bool: return self.power == "on" diff --git a/miio/integrations/philips/light/philips_eyecare.py b/miio/integrations/philips/light/philips_eyecare.py index fe188190b..b9ed3843c 100644 --- a/miio/integrations/philips/light/philips_eyecare.py +++ b/miio/integrations/philips/light/philips_eyecare.py @@ -45,13 +45,11 @@ def brightness(self) -> int: return self.data["bright"] @property - @setting("Eye Fatigue Reminder", setter_name="reminder_on") def reminder(self) -> bool: """Indicates the eye fatigue notification is enabled or not.""" return self.data["notifystatus"] == "on" @property - @setting("Ambient Light", setter_name="ambient_on") def ambient(self) -> bool: """True if the ambient light (second light source) is on.""" return self.data["ambstatus"] == "on" @@ -69,7 +67,6 @@ def ambient_brightness(self) -> int: return self.data["ambvalue"] @property - @setting("Eyecare Mode", setter_name="eyecare_on") def eyecare(self) -> bool: """True if the eyecare mode is on.""" return self.data["eyecare"] == "on" @@ -86,10 +83,6 @@ def scene(self) -> int: return self.data["scene_num"] @property - @setting( - "Smart Night Light", - setter_name="smart_night_light_on", - ) def smart_night_light(self) -> bool: """True if the smart night light mode is on.""" return self.data["bls"] == "on" diff --git a/miio/integrations/philips/light/philips_moonlight.py b/miio/integrations/philips/light/philips_moonlight.py index 8005a4346..b442e8e48 100644 --- a/miio/integrations/philips/light/philips_moonlight.py +++ b/miio/integrations/philips/light/philips_moonlight.py @@ -29,7 +29,6 @@ def power(self) -> str: return self.data["pow"] @property - @setting(name="Power", setter_name="on") def is_on(self) -> bool: return self.power == "on" diff --git a/miio/integrations/shuii/humidifier/airhumidifier_jsq.py b/miio/integrations/shuii/humidifier/airhumidifier_jsq.py index e323c714b..219ef6ee4 100644 --- a/miio/integrations/shuii/humidifier/airhumidifier_jsq.py +++ b/miio/integrations/shuii/humidifier/airhumidifier_jsq.py @@ -66,7 +66,6 @@ def power(self) -> str: return "on" if self.data["power"] == 1 else "off" @property - @setting(name="Power", setter_name="on") def is_on(self) -> bool: """True if device is turned on.""" return self.power == "on" diff --git a/miio/integrations/viomi/viomidishwasher/viomidishwasher.py b/miio/integrations/viomi/viomidishwasher/viomidishwasher.py index 5fabb2e88..55caf6d04 100644 --- a/miio/integrations/viomi/viomidishwasher/viomidishwasher.py +++ b/miio/integrations/viomi/viomidishwasher/viomidishwasher.py @@ -163,7 +163,6 @@ def temperature(self) -> int: return self.data["wash_temp"] @property - @setting(name="Power", setter_name="on") def power(self) -> bool: """Returns the power status of the device.""" From 59f8f220ba4a6c63ed7b67e14a1b036595c37aa5 Mon Sep 17 00:00:00 2001 From: Teemu Rytilahti Date: Sun, 5 Jul 2026 16:08:18 +0200 Subject: [PATCH 7/7] Fix duplicate @property decorators in g1vacuum and roidmivacuum_miot --- miio/integrations/mijia/vacuum/g1vacuum.py | 1 - miio/integrations/roidmi/vacuum/roidmivacuum_miot.py | 1 - 2 files changed, 2 deletions(-) diff --git a/miio/integrations/mijia/vacuum/g1vacuum.py b/miio/integrations/mijia/vacuum/g1vacuum.py index e08985c51..fc20bd033 100644 --- a/miio/integrations/mijia/vacuum/g1vacuum.py +++ b/miio/integrations/mijia/vacuum/g1vacuum.py @@ -186,7 +186,6 @@ def error(self) -> str: except KeyError: return f"Definition missing for error {self.error_code}" - @property @property @sensor("State") def state(self) -> G1State: diff --git a/miio/integrations/roidmi/vacuum/roidmivacuum_miot.py b/miio/integrations/roidmi/vacuum/roidmivacuum_miot.py index 2b77be345..e2eeb091b 100644 --- a/miio/integrations/roidmi/vacuum/roidmivacuum_miot.py +++ b/miio/integrations/roidmi/vacuum/roidmivacuum_miot.py @@ -245,7 +245,6 @@ def error(self) -> str: except KeyError: return f"Definition missing for error {self.error_code}" - @property @property @sensor("Charging State") def charging_state(self) -> ChargingState: