diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 7e7784f..062529f 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,4 +1,4 @@ -name: "Validation And Formatting" +name: "Hassfest and hacs validation" on: push: pull_request: @@ -10,23 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Download repo - with: - fetch-depth: 0 - - uses: actions/setup-python@v2 - name: Setup Python - with: - python-version: '3.8.x' - - uses: actions/cache@v2 - name: Cache - with: - path: | - ~/.cache/pip - key: custom-component-ci + - uses: home-assistant/actions/hassfest@master - uses: hacs/action@main with: - CATEGORY: integration - - uses: KTibow/ha-blueprint@stable - name: CI - with: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + category: integration diff --git a/README.md b/README.md index 31a6adb..7b8dbf3 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,11 @@ # Xiaomi Mi Air Purifier & Xiaomi Mi Air Humidifier +![GitHub actions](https://github.com/syssi/xiaomi_airpurifier/actions/workflows/ci.yaml/badge.svg) +![GitHub stars](https://img.shields.io/github/stars/syssi/xiaomi_airpurifier) +![GitHub forks](https://img.shields.io/github/forks/syssi/xiaomi_airpurifier) +![GitHub watchers](https://img.shields.io/github/watchers/syssi/xiaomi_airpurifier) +[!["Buy Me A Coffee"](https://img.shields.io/badge/buy%20me%20a%20coffee-donate-yellow.svg)](https://www.buymeacoffee.com/syssi) + This is a custom component for home assistant to integrate the Xiaomi Mi Air Purifier 2, Air Purifier 2S, Air Purifier Pro, Air Humidifier, Air Fresh and Pedestal Fan. Please follow the instructions on [Retrieving the Access Token](https://home-assistant.io/components/xiaomi/#retrieving-the-access-token) to get the API token to use in the configuration.yaml file. @@ -30,6 +36,7 @@ This custom component is more or less the beta version of the [official componen | Air Purifier Super 2 | zhimi.airpurifier.sa2 | | | | Air Purifier 3 (2019) | zhimi.airpurifier.ma4 | | | | Air Purifier 3H (2019) | zhimi.airpurifier.mb3 | FJY4031GL(?), XM200017 | 45m2, 380m3/h CADR, 64dB, 38W (max) | +| Air Purifier ZA1 | zhimi.airpurifier.za1 | | | | Air Dog X3 | airdog.airpurifier.x3 | | | | Air Dog X5 | airdog.airpurifier.x5 | | | | Air Dog X7SM | airdog.airpurifier.x7sm | | | @@ -549,7 +556,10 @@ This paragraph was moved to [docs/dmaker-airfresh-t2017.md](docs/dmaker-airfresh ## Install -You can install this custom component by adding this repository ([https://github.com/syssi/xiaomi_airpurifier](https://github.com/syssi/xiaomi_airpurifier/)) to [HACS](https://hacs.xyz/) in the settings menu of HACS first. You will find the custom component in the integration menu afterwards, look for 'Xiaomi Mi Air Purifier and Xiaomi Mi Air Humidifier Integration'. Alternatively, you can install it manually by copying the custom_component folder to your Home Assistant configuration folder. +You can install this custom component via [HACS](https://hacs.xyz/). Search for for 'Xiaomi Mi Air Purifier and Xiaomi Mi Air Humidifier Integration' at the integration page of HACS. Alternatively, you can install it manually by copying the custom_compon +ent folder to your Home Assistant configuration folder. + +As next step you have to setup the custom component at your `configuration.yaml`. This custom component doesn't provide a `config-flow` right now. A restart of Home Assistant is required afterwards. ## Setup diff --git a/custom_components/xiaomi_miio_airpurifier/fan.py b/custom_components/xiaomi_miio_airpurifier/fan.py index 44120ee..0de7727 100644 --- a/custom_components/xiaomi_miio_airpurifier/fan.py +++ b/custom_components/xiaomi_miio_airpurifier/fan.py @@ -3,6 +3,7 @@ from enum import Enum from functools import partial import logging +from typing import Optional from miio import ( # pylint: disable=import-error AirDogX3, @@ -93,6 +94,10 @@ ) from homeassistant.exceptions import PlatformNotReady import homeassistant.helpers.config_validation as cv +from homeassistant.util.percentage import ( + ordered_list_item_to_percentage, + percentage_to_ordered_list_item, +) _LOGGER = logging.getLogger(__name__) @@ -120,6 +125,7 @@ MODEL_AIRPURIFIER_2H = "zhimi.airpurifier.mc2" MODEL_AIRPURIFIER_3 = "zhimi.airpurifier.ma4" MODEL_AIRPURIFIER_3H = "zhimi.airpurifier.mb3" +MODEL_AIRPURIFIER_ZA1 = "zhimi.airpurifier.za1" MODEL_AIRPURIFIER_AIRDOG_X3 = "airdog.airpurifier.x3" MODEL_AIRPURIFIER_AIRDOG_X5 = "airdog.airpurifier.x5" MODEL_AIRPURIFIER_AIRDOG_X7SM = "airdog.airpurifier.x7sm" @@ -175,6 +181,7 @@ MODEL_AIRPURIFIER_2H, MODEL_AIRPURIFIER_3, MODEL_AIRPURIFIER_3H, + MODEL_AIRPURIFIER_ZA1, MODEL_AIRPURIFIER_AIRDOG_X3, MODEL_AIRPURIFIER_AIRDOG_X5, MODEL_AIRPURIFIER_AIRDOG_X7SM, @@ -305,7 +312,7 @@ # Fan Leshow SS4 ATTR_ERROR_DETECTED = "error_detected" -PURIFIER_MIOT = [MODEL_AIRPURIFIER_3, MODEL_AIRPURIFIER_3H] +PURIFIER_MIOT = [MODEL_AIRPURIFIER_3, MODEL_AIRPURIFIER_3H, MODEL_AIRPURIFIER_ZA1] HUMIDIFIER_MIOT = [MODEL_AIRHUMIDIFIER_CA4] # AirDogX7SM @@ -667,6 +674,9 @@ FAN_SPEED_LEVEL3: 3, } +FAN_SPEEDS_1C = list(FAN_PRESET_MODES_1C) +FAN_SPEEDS_1C.remove(SPEED_OFF) + OPERATION_MODES_AIRPURIFIER = ["Auto", "Silent", "Favorite", "Idle"] OPERATION_MODES_AIRPURIFIER_PRO = ["Auto", "Silent", "Favorite"] OPERATION_MODES_AIRPURIFIER_PRO_V7 = OPERATION_MODES_AIRPURIFIER_PRO @@ -2371,11 +2381,11 @@ async def async_set_percentage(self, percentage: int) -> None: async def async_set_direction(self, direction: str) -> None: """Set the direction of the fan.""" - if direction == 'forward': - direction = 'right' + if direction == "forward": + direction = "right" - if direction == 'reverse': - direction = 'left' + if direction == "reverse": + direction = "left" if self._oscillate: await self._try_command( @@ -2739,7 +2749,7 @@ def __init__(self, name, device, model, unique_id, retries): @property def supported_features(self) -> int: """Supported features.""" - return SUPPORT_PRESET_MODE | SUPPORT_OSCILLATE + return SUPPORT_SET_SPEED | SUPPORT_PRESET_MODE | SUPPORT_OSCILLATE async def async_update(self): """Fetch state from the device.""" @@ -2784,6 +2794,16 @@ async def async_update(self): self._retry, ) + @property + def percentage(self) -> Optional[int]: + """Return the current speed percentage.""" + return ordered_list_item_to_percentage(FAN_SPEEDS_1C, self._preset_mode) + + @property + def speed_count(self) -> int: + """Return the number of speeds the fan supports.""" + return len(FAN_SPEEDS_1C) + @property def preset_modes(self): """Get the list of available preset modes.""" @@ -2801,12 +2821,36 @@ async def async_set_preset_mode(self, preset_mode: str) -> None: """Set the preset mode of the fan.""" _LOGGER.debug("Setting the preset mode to: %s", preset_mode) + if not self._state: + await self._try_command( + "Turning the miio device on failed.", self._device.on + ) await self._try_command( "Setting preset mode of the miio device failed.", self._device.set_speed, FAN_PRESET_MODES_1C[preset_mode], ) + async def async_set_percentage(self, percentage: int) -> None: + """Set the speed percentage of the fan.""" + _LOGGER.debug("Setting the fan speed percentage to: %s", percentage) + + if percentage == 0: + await self.async_turn_off() + return + + if not self._state: + await self._try_command( + "Turning the miio device on failed.", self._device.on + ) + await self._try_command( + "Setting preset mode of the miio device failed.", + self._device.set_speed, + FAN_PRESET_MODES_1C[ + percentage_to_ordered_list_item(FAN_SPEEDS_1C, percentage) + ], + ) + @property def oscillating(self): """Return the oscillation state.""" diff --git a/custom_components/xiaomi_miio_airpurifier/manifest.json b/custom_components/xiaomi_miio_airpurifier/manifest.json index 0b27439..cf7377a 100644 --- a/custom_components/xiaomi_miio_airpurifier/manifest.json +++ b/custom_components/xiaomi_miio_airpurifier/manifest.json @@ -1,14 +1,14 @@ { "domain": "xiaomi_miio_airpurifier", "name": "Xiaomi Mi Air Purifier, Air Humidifier, Air Fresh and Pedestal Fan Integration", - "version": "0.6.9", + "version": "0.6.12", "iot_class": "local_polling", "config_flow": false, "documentation": "https://github.com/syssi/xiaomi_airpurifier", "issue_tracker": "https://github.com/syssi/xiaomi_airpurifier/issues", "requirements": [ "construct==2.10.56", - "python-miio>=0.5.6" + "python-miio>=0.5.7" ], "dependencies": [], "codeowners": [ diff --git a/custom_components/xiaomi_miio_airpurifier/services.yaml b/custom_components/xiaomi_miio_airpurifier/services.yaml index bd93de8..a7af806 100644 --- a/custom_components/xiaomi_miio_airpurifier/services.yaml +++ b/custom_components/xiaomi_miio_airpurifier/services.yaml @@ -155,5 +155,3 @@ fan_set_filters_cleaned: entity_id: description: Name of the xiaomi miio entity. example: "xiaomi_miio_airpurifier.xiaomi_miio_device" - -