mirror of
https://github.com/home-assistant/core.git
synced 2026-05-25 02:05:11 +02:00
Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 748a9842af | |||
| 55786dbdfc | |||
| e88c03a437 | |||
| dbc0dc1ea6 | |||
| 31271876bf | |||
| d5c31332b5 | |||
| 3f0c93c26c | |||
| 07ed913ba2 | |||
| b7905b163f | |||
| c712b07da3 |
@@ -1,9 +0,0 @@
|
||||
{
|
||||
"features": {
|
||||
"ghcr.io/devcontainers/features/github-cli:1": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "ghcr.io/devcontainers/features/github-cli@sha256:d22f50b70ed75339b4eed1ba9ecde3a1791f90e88d37936517e3bace0bbad671",
|
||||
"integrity": "sha256:d22f50b70ed75339b4eed1ba9ecde3a1791f90e88d37936517e3bace0bbad671"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,6 @@ Dockerfile.dev linguist-language=Dockerfile
|
||||
# Generated files
|
||||
CODEOWNERS linguist-generated=true
|
||||
homeassistant/generated/*.py linguist-generated=true
|
||||
pylint/plugins/pylint_home_assistant/generated/*.py linguist-generated=true
|
||||
machine/* linguist-generated=true
|
||||
mypy.ini linguist-generated=true
|
||||
requirements.txt linguist-generated=true
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
name: Cache and install APT packages
|
||||
description: >-
|
||||
Wraps awalsh128/cache-apt-pkgs-action with the workarounds Home Assistant CI
|
||||
needs. Removes the conflicting Microsoft apt source before any apt run, and
|
||||
points the dynamic linker at the host's multiarch lib subdirectories so
|
||||
shared libraries that rely on update-alternatives or postinst-managed paths
|
||||
(eg libblas, liblapack pulled in by ffmpeg) stay reachable since the upstream
|
||||
action does not execute postinst scripts on cache restore.
|
||||
|
||||
inputs:
|
||||
packages:
|
||||
description: Space-delimited list of apt packages to install.
|
||||
required: true
|
||||
version:
|
||||
description: Cache version. Bump to invalidate the cache.
|
||||
required: false
|
||||
default: "1"
|
||||
execute_install_scripts:
|
||||
description: >-
|
||||
Pass-through to awalsh128/cache-apt-pkgs-action. Postinst scripts are not
|
||||
actually cached by the upstream action, so this is largely a no-op today.
|
||||
required: false
|
||||
default: "false"
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Remove conflicting Microsoft apt source
|
||||
shell: bash
|
||||
run: sudo rm -f /etc/apt/sources.list.d/microsoft-prod.list
|
||||
- name: Install apt packages via cache
|
||||
uses: awalsh128/cache-apt-pkgs-action@acb598e5ddbc6f68a970c5da0688d2f3a9f04d05 # v1.5.3
|
||||
with:
|
||||
packages: ${{ inputs.packages }}
|
||||
version: ${{ inputs.version }}
|
||||
execute_install_scripts: ${{ inputs.execute_install_scripts }}
|
||||
- name: Refresh dynamic linker cache
|
||||
shell: bash
|
||||
run: |
|
||||
# awalsh128/cache-apt-pkgs-action does not run postinst scripts on
|
||||
# cache restore, so update-alternatives symlinks (eg the one libblas
|
||||
# creates at /usr/lib/<multiarch>/libblas.so.3) are never produced.
|
||||
# Add every /usr/lib/<multiarch> subdirectory that holds shared
|
||||
# libraries to the ldconfig search path so the dynamic linker still
|
||||
# finds them. Use dpkg-architecture to derive the host's multiarch
|
||||
# tuple so this works on non-x86_64 runners too.
|
||||
multiarch="$(dpkg-architecture -qDEB_HOST_MULTIARCH)"
|
||||
find "/usr/lib/${multiarch}" -mindepth 2 -maxdepth 2 \
|
||||
-name '*.so.*' -printf '%h\n' \
|
||||
| sort -u \
|
||||
| sudo tee /etc/ld.so.conf.d/zzz-cache-apt-extras.conf > /dev/null
|
||||
sudo ldconfig
|
||||
@@ -0,0 +1,42 @@
|
||||
name: Set up uv and managed Python
|
||||
description: >-
|
||||
Pins uv (avoids the raw.githubusercontent.com manifest fetch on cache miss)
|
||||
and proactively installs the requested Python so cached venvs created with
|
||||
`uv venv` resolve their interpreter symlinks in jobs that only restore the
|
||||
venv. setup-uv alone only sets UV_PYTHON, it does not actually fetch the
|
||||
interpreter until uv first uses it, so jobs that just activate the venv
|
||||
blow up with broken symlinks on cache hit.
|
||||
|
||||
inputs:
|
||||
python-version:
|
||||
description: The Python version uv should install and use.
|
||||
required: true
|
||||
uv-version:
|
||||
description: The uv version setup-uv should install.
|
||||
required: true
|
||||
|
||||
outputs:
|
||||
python-version:
|
||||
description: The Python version uv reports as installed.
|
||||
value: ${{ steps.uv.outputs.python-version }}
|
||||
|
||||
runs:
|
||||
using: composite
|
||||
steps:
|
||||
- name: Set up uv
|
||||
id: uv
|
||||
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
||||
with:
|
||||
version: ${{ inputs.uv-version }}
|
||||
python-version: ${{ inputs.python-version }}
|
||||
# Persist astral's managed Python across jobs so 'uv venv' below is
|
||||
# fast on the second job onwards.
|
||||
cache-python: true
|
||||
# Lint-only and codegen jobs touch no Python deps, so the post-step
|
||||
# cache save would otherwise abort the job.
|
||||
ignore-nothing-to-cache: true
|
||||
- name: Install Python interpreter
|
||||
shell: bash
|
||||
env:
|
||||
PYTHON_VERSION: ${{ inputs.python-version }}
|
||||
run: uv python install "${PYTHON_VERSION}"
|
||||
@@ -25,7 +25,6 @@ This repository contains the core of Home Assistant, a Python 3 based home autom
|
||||
|
||||
- When entering a new environment or worktree, run `script/setup` to set up the virtual environment with all development dependencies (pylint, pre-commit hooks, etc.). This is required before committing.
|
||||
- .vscode/tasks.json contains useful commands used for development.
|
||||
- After finishing a code session, run `uv run prek run --all-files` to check for linting and formatting issues.
|
||||
|
||||
## Python Syntax Notes
|
||||
|
||||
|
||||
+134
-242
@@ -37,7 +37,7 @@ on:
|
||||
type: boolean
|
||||
|
||||
env:
|
||||
CACHE_VERSION: 3
|
||||
CACHE_VERSION: 4
|
||||
MYPY_CACHE_VERSION: 1
|
||||
HA_SHORT_VERSION: "2026.6"
|
||||
ADDITIONAL_PYTHON_VERSIONS: "[]"
|
||||
@@ -60,9 +60,7 @@ env:
|
||||
# - 15.2 is the latest (as of 9 Feb 2023)
|
||||
POSTGRESQL_VERSIONS: "['postgres:12.14','postgres:15.2']"
|
||||
UV_CACHE_DIR: /tmp/uv-cache
|
||||
APT_CACHE_BASE: /home/runner/work/apt
|
||||
APT_CACHE_DIR: /home/runner/work/apt/cache
|
||||
APT_LIST_CACHE_DIR: /home/runner/work/apt/lists
|
||||
APT_CACHE_VERSION: 1
|
||||
SQLALCHEMY_WARN_20: 1
|
||||
PYTHONASYNCIODEBUG: 1
|
||||
HASS_CI: 1
|
||||
@@ -86,12 +84,13 @@ jobs:
|
||||
core: ${{ steps.core.outputs.changes }}
|
||||
integrations_glob: ${{ steps.info.outputs.integrations_glob }}
|
||||
integrations: ${{ steps.integrations.outputs.changes }}
|
||||
apt_cache_key: ${{ steps.generate_apt_cache_key.outputs.key }}
|
||||
python_cache_key: ${{ steps.generate_python_cache_key.outputs.key }}
|
||||
requirements: ${{ steps.core.outputs.requirements }}
|
||||
mariadb_groups: ${{ steps.info.outputs.mariadb_groups }}
|
||||
postgresql_groups: ${{ steps.info.outputs.postgresql_groups }}
|
||||
python_versions: ${{ steps.info.outputs.python_versions }}
|
||||
default_python: ${{ steps.info.outputs.default_python }}
|
||||
uv_version: ${{ steps.info.outputs.uv_version }}
|
||||
test_full_suite: ${{ steps.info.outputs.test_full_suite }}
|
||||
test_group_count: ${{ steps.info.outputs.test_group_count }}
|
||||
test_groups: ${{ steps.info.outputs.test_groups }}
|
||||
@@ -116,10 +115,6 @@ jobs:
|
||||
# Include HA_SHORT_VERSION to force the immediate creation
|
||||
# of a new uv cache entry after a version bump.
|
||||
echo "key=venv-${CACHE_VERSION}-${HA_SHORT_VERSION}-${HASH_REQUIREMENTS_TEST}-${HASH_REQUIREMENTS}-${HASH_REQUIREMENTS_ALL}-${HASH_PACKAGE_CONSTRAINTS}-${HASH_GEN_REQUIREMENTS}" >> $GITHUB_OUTPUT
|
||||
- name: Generate partial apt restore key
|
||||
id: generate_apt_cache_key
|
||||
run: |
|
||||
echo "key=$(lsb_release -rs)-apt-${CACHE_VERSION}-${HA_SHORT_VERSION}" >> $GITHUB_OUTPUT
|
||||
- name: Filter for core changes
|
||||
uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1
|
||||
id: core
|
||||
@@ -242,6 +237,11 @@ jobs:
|
||||
echo "postgresql_groups=${postgresql_groups}" >> $GITHUB_OUTPUT
|
||||
echo "python_versions: ${all_python_versions}"
|
||||
echo "python_versions=${all_python_versions}" >> $GITHUB_OUTPUT
|
||||
echo "default_python: ${default_python}"
|
||||
echo "default_python=${default_python}" >> $GITHUB_OUTPUT
|
||||
uv_version=$(grep '^uv==' requirements.txt | cut -d'=' -f3)
|
||||
echo "uv_version: ${uv_version}"
|
||||
echo "uv_version=${uv_version}" >> $GITHUB_OUTPUT
|
||||
echo "test_full_suite: ${test_full_suite}"
|
||||
echo "test_full_suite=${test_full_suite}" >> $GITHUB_OUTPUT
|
||||
echo "integrations_glob: ${integrations_glob}"
|
||||
@@ -281,7 +281,7 @@ jobs:
|
||||
echo "::add-matcher::.github/workflows/matchers/check-executables-have-shebangs.json"
|
||||
echo "::add-matcher::.github/workflows/matchers/codespell.json"
|
||||
- name: Run prek
|
||||
uses: j178/prek-action@bdca6f102f98e2b4c7029491a53dfd366469e33d # v2.0.4
|
||||
uses: j178/prek-action@6ad80277337ad479fe43bd70701c3f7f8aa74db3 # v2.0.3
|
||||
env:
|
||||
PREK_SKIP: no-commit-to-branch,mypy,pylint,gen_requirements_all,hassfest,hassfest-metadata,hassfest-mypy-config,zizmor
|
||||
RUFF_OUTPUT_FORMAT: github
|
||||
@@ -302,7 +302,7 @@ jobs:
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Run zizmor
|
||||
uses: j178/prek-action@bdca6f102f98e2b4c7029491a53dfd366469e33d # v2.0.4
|
||||
uses: j178/prek-action@6ad80277337ad479fe43bd70701c3f7f8aa74db3 # v2.0.3
|
||||
with:
|
||||
extra-args: --all-files zizmor
|
||||
|
||||
@@ -351,12 +351,12 @@ jobs:
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
- name: Set up uv and Python ${{ matrix.python-version }}
|
||||
id: python
|
||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
uses: ./.github/actions/setup-uv-python
|
||||
with:
|
||||
uv-version: ${{ needs.info.outputs.uv_version }}
|
||||
python-version: ${{ matrix.python-version }}
|
||||
check-latest: true
|
||||
- name: Restore base Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
@@ -384,80 +384,41 @@ jobs:
|
||||
path: ${{ env.UV_CACHE_DIR }}
|
||||
key: ${{ steps.generate-uv-key.outputs.full_key }}
|
||||
restore-keys: ${{ steps.generate-uv-key.outputs.partial_key }}
|
||||
- name: Check if apt cache exists
|
||||
id: cache-apt-check
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
lookup-only: ${{ steps.cache-venv.outputs.cache-hit == 'true' }}
|
||||
path: |
|
||||
${{ env.APT_CACHE_DIR }}
|
||||
${{ env.APT_LIST_CACHE_DIR }}
|
||||
key: >-
|
||||
${{ runner.os }}-${{ runner.arch }}-${{ needs.info.outputs.apt_cache_key }}
|
||||
- name: Install additional OS dependencies
|
||||
if: |
|
||||
steps.cache-venv.outputs.cache-hit != 'true'
|
||||
|| steps.cache-apt-check.outputs.cache-hit != 'true'
|
||||
id: install-os-deps
|
||||
if: steps.cache-venv.outputs.cache-hit != 'true'
|
||||
timeout-minutes: 10
|
||||
env:
|
||||
APT_CACHE_HIT: ${{ steps.cache-apt-check.outputs.cache-hit }}
|
||||
run: |
|
||||
sudo rm /etc/apt/sources.list.d/microsoft-prod.list
|
||||
if [[ "${APT_CACHE_HIT}" != 'true' ]]; then
|
||||
mkdir -p ${APT_CACHE_DIR}
|
||||
mkdir -p ${APT_LIST_CACHE_DIR}
|
||||
fi
|
||||
|
||||
sudo apt-get update \
|
||||
-o Dir::Cache=${APT_CACHE_DIR} \
|
||||
-o Dir::State::Lists=${APT_LIST_CACHE_DIR}
|
||||
sudo apt-get -y install \
|
||||
-o Dir::Cache=${APT_CACHE_DIR} \
|
||||
-o Dir::State::Lists=${APT_LIST_CACHE_DIR} \
|
||||
bluez \
|
||||
ffmpeg \
|
||||
libturbojpeg \
|
||||
libxml2-utils \
|
||||
libavcodec-dev \
|
||||
libavdevice-dev \
|
||||
libavfilter-dev \
|
||||
libavformat-dev \
|
||||
libavutil-dev \
|
||||
libswresample-dev \
|
||||
libswscale-dev \
|
||||
libudev-dev
|
||||
|
||||
if [[ "${APT_CACHE_HIT}" != 'true' ]]; then
|
||||
sudo chmod -R 755 ${APT_CACHE_BASE}
|
||||
fi
|
||||
- name: Save apt cache
|
||||
if: |
|
||||
always()
|
||||
&& steps.cache-apt-check.outputs.cache-hit != 'true'
|
||||
&& steps.install-os-deps.outcome == 'success'
|
||||
uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
uses: ./.github/actions/cache-apt-packages
|
||||
with:
|
||||
path: |
|
||||
${{ env.APT_CACHE_DIR }}
|
||||
${{ env.APT_LIST_CACHE_DIR }}
|
||||
key: >-
|
||||
${{ runner.os }}-${{ runner.arch }}-${{ needs.info.outputs.apt_cache_key }}
|
||||
packages: >-
|
||||
bluez
|
||||
ffmpeg
|
||||
libturbojpeg
|
||||
libxml2-utils
|
||||
libavcodec-dev
|
||||
libavdevice-dev
|
||||
libavfilter-dev
|
||||
libavformat-dev
|
||||
libavutil-dev
|
||||
libswresample-dev
|
||||
libswscale-dev
|
||||
libudev-dev
|
||||
version: ${{ env.APT_CACHE_VERSION }}
|
||||
execute_install_scripts: true
|
||||
- name: Create Python virtual environment
|
||||
if: steps.cache-venv.outputs.cache-hit != 'true'
|
||||
id: create-venv
|
||||
env:
|
||||
PYTHON_VERSION: ${{ steps.python.outputs.python-version }}
|
||||
run: |
|
||||
python -m venv venv
|
||||
uv venv venv --python "${PYTHON_VERSION}"
|
||||
. venv/bin/activate
|
||||
python --version
|
||||
pip install "$(grep '^uv' < requirements.txt)"
|
||||
uv pip install -U "pip>=25.2"
|
||||
uv pip install -r requirements.txt
|
||||
uv pip install -r requirements_all.txt -r requirements_test.txt
|
||||
uv pip install -e . --config-settings editable_mode=compat
|
||||
- name: Dump pip freeze
|
||||
run: |
|
||||
python -m venv venv
|
||||
. venv/bin/activate
|
||||
python --version
|
||||
uv pip freeze >> pip_freeze.txt
|
||||
@@ -506,36 +467,22 @@ jobs:
|
||||
&& github.event.inputs.mypy-only != 'true'
|
||||
&& github.event.inputs.audit-licenses-only != 'true'
|
||||
steps:
|
||||
- name: Restore apt cache
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: |
|
||||
${{ env.APT_CACHE_DIR }}
|
||||
${{ env.APT_LIST_CACHE_DIR }}
|
||||
fail-on-cache-miss: true
|
||||
key: >-
|
||||
${{ runner.os }}-${{ runner.arch }}-${{ needs.info.outputs.apt_cache_key }}
|
||||
- name: Install additional OS dependencies
|
||||
timeout-minutes: 10
|
||||
run: |
|
||||
sudo rm /etc/apt/sources.list.d/microsoft-prod.list
|
||||
sudo apt-get update \
|
||||
-o Dir::Cache=${APT_CACHE_DIR} \
|
||||
-o Dir::State::Lists=${APT_LIST_CACHE_DIR}
|
||||
sudo apt-get -y install \
|
||||
-o Dir::Cache=${APT_CACHE_DIR} \
|
||||
-o Dir::State::Lists=${APT_LIST_CACHE_DIR} \
|
||||
libturbojpeg
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Install additional OS dependencies
|
||||
timeout-minutes: 10
|
||||
uses: ./.github/actions/cache-apt-packages
|
||||
with:
|
||||
packages: libturbojpeg
|
||||
version: ${{ env.APT_CACHE_VERSION }}
|
||||
- name: Set up Python
|
||||
id: python
|
||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
uses: ./.github/actions/setup-uv-python
|
||||
with:
|
||||
python-version-file: ".python-version"
|
||||
check-latest: true
|
||||
uv-version: ${{ needs.info.outputs.uv_version }}
|
||||
python-version: ${{ needs.info.outputs.default_python }}
|
||||
- name: Restore full Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
@@ -569,10 +516,10 @@ jobs:
|
||||
persist-credentials: false
|
||||
- name: Set up Python
|
||||
id: python
|
||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
uses: ./.github/actions/setup-uv-python
|
||||
with:
|
||||
python-version-file: ".python-version"
|
||||
check-latest: true
|
||||
uv-version: ${{ needs.info.outputs.uv_version }}
|
||||
python-version: ${{ needs.info.outputs.default_python }}
|
||||
- name: Restore full Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
@@ -605,10 +552,10 @@ jobs:
|
||||
persist-credentials: false
|
||||
- name: Set up Python
|
||||
id: python
|
||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
uses: ./.github/actions/setup-uv-python
|
||||
with:
|
||||
python-version-file: ".python-version"
|
||||
check-latest: true
|
||||
uv-version: ${{ needs.info.outputs.uv_version }}
|
||||
python-version: ${{ needs.info.outputs.default_python }}
|
||||
- name: Run gen_copilot_instructions.py
|
||||
run: |
|
||||
python -m script.gen_copilot_instructions validate
|
||||
@@ -660,10 +607,10 @@ jobs:
|
||||
persist-credentials: false
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
id: python
|
||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
uses: ./.github/actions/setup-uv-python
|
||||
with:
|
||||
uv-version: ${{ needs.info.outputs.uv_version }}
|
||||
python-version: ${{ matrix.python-version }}
|
||||
check-latest: true
|
||||
- name: Restore full Python ${{ matrix.python-version }} virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
@@ -711,10 +658,10 @@ jobs:
|
||||
persist-credentials: false
|
||||
- name: Set up Python
|
||||
id: python
|
||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
uses: ./.github/actions/setup-uv-python
|
||||
with:
|
||||
python-version-file: ".python-version"
|
||||
check-latest: true
|
||||
uv-version: ${{ needs.info.outputs.uv_version }}
|
||||
python-version: ${{ needs.info.outputs.default_python }}
|
||||
- name: Restore full Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
@@ -764,10 +711,10 @@ jobs:
|
||||
persist-credentials: false
|
||||
- name: Set up Python
|
||||
id: python
|
||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
uses: ./.github/actions/setup-uv-python
|
||||
with:
|
||||
python-version-file: ".python-version"
|
||||
check-latest: true
|
||||
uv-version: ${{ needs.info.outputs.uv_version }}
|
||||
python-version: ${{ needs.info.outputs.default_python }}
|
||||
- name: Restore full Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
@@ -815,10 +762,10 @@ jobs:
|
||||
persist-credentials: false
|
||||
- name: Set up Python
|
||||
id: python
|
||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
uses: ./.github/actions/setup-uv-python
|
||||
with:
|
||||
python-version-file: ".python-version"
|
||||
check-latest: true
|
||||
uv-version: ${{ needs.info.outputs.uv_version }}
|
||||
python-version: ${{ needs.info.outputs.default_python }}
|
||||
- name: Generate partial mypy restore key
|
||||
id: generate-mypy-key
|
||||
run: |
|
||||
@@ -876,38 +823,26 @@ jobs:
|
||||
- info
|
||||
- base
|
||||
steps:
|
||||
- name: Restore apt cache
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: |
|
||||
${{ env.APT_CACHE_DIR }}
|
||||
${{ env.APT_LIST_CACHE_DIR }}
|
||||
fail-on-cache-miss: true
|
||||
key: >-
|
||||
${{ runner.os }}-${{ runner.arch }}-${{ needs.info.outputs.apt_cache_key }}
|
||||
- name: Install additional OS dependencies
|
||||
timeout-minutes: 10
|
||||
run: |
|
||||
sudo rm /etc/apt/sources.list.d/microsoft-prod.list
|
||||
sudo apt-get update \
|
||||
-o Dir::Cache=${APT_CACHE_DIR} \
|
||||
-o Dir::State::Lists=${APT_LIST_CACHE_DIR}
|
||||
sudo apt-get -y install \
|
||||
-o Dir::Cache=${APT_CACHE_DIR} \
|
||||
-o Dir::State::Lists=${APT_LIST_CACHE_DIR} \
|
||||
bluez \
|
||||
ffmpeg \
|
||||
libturbojpeg
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Install additional OS dependencies
|
||||
timeout-minutes: 10
|
||||
uses: ./.github/actions/cache-apt-packages
|
||||
with:
|
||||
packages: >-
|
||||
bluez
|
||||
ffmpeg
|
||||
libturbojpeg
|
||||
version: ${{ env.APT_CACHE_VERSION }}
|
||||
execute_install_scripts: true
|
||||
- name: Set up Python
|
||||
id: python
|
||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
uses: ./.github/actions/setup-uv-python
|
||||
with:
|
||||
python-version-file: ".python-version"
|
||||
check-latest: true
|
||||
uv-version: ${{ needs.info.outputs.uv_version }}
|
||||
python-version: ${{ needs.info.outputs.default_python }}
|
||||
- name: Restore full Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
@@ -952,39 +887,27 @@ jobs:
|
||||
python-version: ${{ fromJson(needs.info.outputs.python_versions) }}
|
||||
group: ${{ fromJson(needs.info.outputs.test_groups) }}
|
||||
steps:
|
||||
- name: Restore apt cache
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: |
|
||||
${{ env.APT_CACHE_DIR }}
|
||||
${{ env.APT_LIST_CACHE_DIR }}
|
||||
fail-on-cache-miss: true
|
||||
key: >-
|
||||
${{ runner.os }}-${{ runner.arch }}-${{ needs.info.outputs.apt_cache_key }}
|
||||
- name: Install additional OS dependencies
|
||||
timeout-minutes: 10
|
||||
run: |
|
||||
sudo rm /etc/apt/sources.list.d/microsoft-prod.list
|
||||
sudo apt-get update \
|
||||
-o Dir::Cache=${APT_CACHE_DIR} \
|
||||
-o Dir::State::Lists=${APT_LIST_CACHE_DIR}
|
||||
sudo apt-get -y install \
|
||||
-o Dir::Cache=${APT_CACHE_DIR} \
|
||||
-o Dir::State::Lists=${APT_LIST_CACHE_DIR} \
|
||||
bluez \
|
||||
ffmpeg \
|
||||
libturbojpeg \
|
||||
libxml2-utils
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Install additional OS dependencies
|
||||
timeout-minutes: 10
|
||||
uses: ./.github/actions/cache-apt-packages
|
||||
with:
|
||||
packages: >-
|
||||
bluez
|
||||
ffmpeg
|
||||
libturbojpeg
|
||||
libxml2-utils
|
||||
version: ${{ env.APT_CACHE_VERSION }}
|
||||
execute_install_scripts: true
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
id: python
|
||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
uses: ./.github/actions/setup-uv-python
|
||||
with:
|
||||
uv-version: ${{ needs.info.outputs.uv_version }}
|
||||
python-version: ${{ matrix.python-version }}
|
||||
check-latest: true
|
||||
- name: Restore full Python ${{ matrix.python-version }} virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
@@ -1105,40 +1028,28 @@ jobs:
|
||||
python-version: ${{ fromJson(needs.info.outputs.python_versions) }}
|
||||
mariadb-group: ${{ fromJson(needs.info.outputs.mariadb_groups) }}
|
||||
steps:
|
||||
- name: Restore apt cache
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: |
|
||||
${{ env.APT_CACHE_DIR }}
|
||||
${{ env.APT_LIST_CACHE_DIR }}
|
||||
fail-on-cache-miss: true
|
||||
key: >-
|
||||
${{ runner.os }}-${{ runner.arch }}-${{ needs.info.outputs.apt_cache_key }}
|
||||
- name: Install additional OS dependencies
|
||||
timeout-minutes: 10
|
||||
run: |
|
||||
sudo rm /etc/apt/sources.list.d/microsoft-prod.list
|
||||
sudo apt-get update \
|
||||
-o Dir::Cache=${APT_CACHE_DIR} \
|
||||
-o Dir::State::Lists=${APT_LIST_CACHE_DIR}
|
||||
sudo apt-get -y install \
|
||||
-o Dir::Cache=${APT_CACHE_DIR} \
|
||||
-o Dir::State::Lists=${APT_LIST_CACHE_DIR} \
|
||||
bluez \
|
||||
ffmpeg \
|
||||
libturbojpeg \
|
||||
libmariadb-dev-compat \
|
||||
libxml2-utils
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Install additional OS dependencies
|
||||
timeout-minutes: 10
|
||||
uses: ./.github/actions/cache-apt-packages
|
||||
with:
|
||||
packages: >-
|
||||
bluez
|
||||
ffmpeg
|
||||
libturbojpeg
|
||||
libmariadb-dev-compat
|
||||
libxml2-utils
|
||||
version: ${{ env.APT_CACHE_VERSION }}
|
||||
execute_install_scripts: true
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
id: python
|
||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
uses: ./.github/actions/setup-uv-python
|
||||
with:
|
||||
uv-version: ${{ needs.info.outputs.uv_version }}
|
||||
python-version: ${{ matrix.python-version }}
|
||||
check-latest: true
|
||||
- name: Restore full Python ${{ matrix.python-version }} virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
@@ -1266,42 +1177,35 @@ jobs:
|
||||
python-version: ${{ fromJson(needs.info.outputs.python_versions) }}
|
||||
postgresql-group: ${{ fromJson(needs.info.outputs.postgresql_groups) }}
|
||||
steps:
|
||||
- name: Restore apt cache
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: |
|
||||
${{ env.APT_CACHE_DIR }}
|
||||
${{ env.APT_LIST_CACHE_DIR }}
|
||||
fail-on-cache-miss: true
|
||||
key: >-
|
||||
${{ runner.os }}-${{ runner.arch }}-${{ needs.info.outputs.apt_cache_key }}
|
||||
- name: Install additional OS dependencies
|
||||
timeout-minutes: 10
|
||||
run: |
|
||||
sudo rm /etc/apt/sources.list.d/microsoft-prod.list
|
||||
sudo apt-get update \
|
||||
-o Dir::Cache=${APT_CACHE_DIR} \
|
||||
-o Dir::State::Lists=${APT_LIST_CACHE_DIR}
|
||||
sudo apt-get -y install \
|
||||
-o Dir::Cache=${APT_CACHE_DIR} \
|
||||
-o Dir::State::Lists=${APT_LIST_CACHE_DIR} \
|
||||
bluez \
|
||||
ffmpeg \
|
||||
libturbojpeg \
|
||||
libxml2-utils
|
||||
sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y
|
||||
sudo apt-get -y install \
|
||||
postgresql-server-dev-14
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Install additional OS dependencies
|
||||
timeout-minutes: 10
|
||||
uses: ./.github/actions/cache-apt-packages
|
||||
with:
|
||||
packages: >-
|
||||
bluez
|
||||
ffmpeg
|
||||
libturbojpeg
|
||||
libxml2-utils
|
||||
version: ${{ env.APT_CACHE_VERSION }}
|
||||
execute_install_scripts: true
|
||||
- name: Set up PostgreSQL apt repository
|
||||
run: sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y
|
||||
- name: Cache PostgreSQL development headers
|
||||
timeout-minutes: 10
|
||||
uses: ./.github/actions/cache-apt-packages
|
||||
with:
|
||||
packages: postgresql-server-dev-14
|
||||
version: ${{ env.APT_CACHE_VERSION }}
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
id: python
|
||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
uses: ./.github/actions/setup-uv-python
|
||||
with:
|
||||
uv-version: ${{ needs.info.outputs.uv_version }}
|
||||
python-version: ${{ matrix.python-version }}
|
||||
check-latest: true
|
||||
- name: Restore full Python ${{ matrix.python-version }} virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
@@ -1449,39 +1353,27 @@ jobs:
|
||||
python-version: ${{ fromJson(needs.info.outputs.python_versions) }}
|
||||
group: ${{ fromJson(needs.info.outputs.test_groups) }}
|
||||
steps:
|
||||
- name: Restore apt cache
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: |
|
||||
${{ env.APT_CACHE_DIR }}
|
||||
${{ env.APT_LIST_CACHE_DIR }}
|
||||
fail-on-cache-miss: true
|
||||
key: >-
|
||||
${{ runner.os }}-${{ runner.arch }}-${{ needs.info.outputs.apt_cache_key }}
|
||||
- name: Install additional OS dependencies
|
||||
timeout-minutes: 10
|
||||
run: |
|
||||
sudo rm /etc/apt/sources.list.d/microsoft-prod.list
|
||||
sudo apt-get update \
|
||||
-o Dir::Cache=${APT_CACHE_DIR} \
|
||||
-o Dir::State::Lists=${APT_LIST_CACHE_DIR}
|
||||
sudo apt-get -y install \
|
||||
-o Dir::Cache=${APT_CACHE_DIR} \
|
||||
-o Dir::State::Lists=${APT_LIST_CACHE_DIR} \
|
||||
bluez \
|
||||
ffmpeg \
|
||||
libturbojpeg \
|
||||
libxml2-utils
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Install additional OS dependencies
|
||||
timeout-minutes: 10
|
||||
uses: ./.github/actions/cache-apt-packages
|
||||
with:
|
||||
packages: >-
|
||||
bluez
|
||||
ffmpeg
|
||||
libturbojpeg
|
||||
libxml2-utils
|
||||
version: ${{ env.APT_CACHE_VERSION }}
|
||||
execute_install_scripts: true
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
id: python
|
||||
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
|
||||
uses: ./.github/actions/setup-uv-python
|
||||
with:
|
||||
uv-version: ${{ needs.info.outputs.uv_version }}
|
||||
python-version: ${{ matrix.python-version }}
|
||||
check-latest: true
|
||||
- name: Restore full Python ${{ matrix.python-version }} virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
|
||||
@@ -28,11 +28,11 @@ jobs:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5
|
||||
uses: github/codeql-action/init@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4
|
||||
with:
|
||||
languages: python
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@9e0d7b8d25671d64c341c19c0152d693099fb5ba # v4.35.5
|
||||
uses: github/codeql-action/analyze@68bde559dea0fdcac2102bfdf6230c5f70eb485e # v4.35.4
|
||||
with:
|
||||
category: "/language:python"
|
||||
|
||||
@@ -15,7 +15,6 @@ This repository contains the core of Home Assistant, a Python 3 based home autom
|
||||
|
||||
- When entering a new environment or worktree, run `script/setup` to set up the virtual environment with all development dependencies (pylint, pre-commit hooks, etc.). This is required before committing.
|
||||
- .vscode/tasks.json contains useful commands used for development.
|
||||
- After finishing a code session, run `uv run prek run --all-files` to check for linting and formatting issues.
|
||||
|
||||
## Python Syntax Notes
|
||||
|
||||
|
||||
Generated
+4
-2
@@ -236,8 +236,8 @@ CLAUDE.md @home-assistant/core
|
||||
/tests/components/blebox/ @bbx-a @swistakm @bkobus-bbx
|
||||
/homeassistant/components/blink/ @fronzbot
|
||||
/tests/components/blink/ @fronzbot
|
||||
/homeassistant/components/blue_current/ @gleeuwen @jtodorova23
|
||||
/tests/components/blue_current/ @gleeuwen @jtodorova23
|
||||
/homeassistant/components/blue_current/ @gleeuwen @NickKoepr @jtodorova23
|
||||
/tests/components/blue_current/ @gleeuwen @NickKoepr @jtodorova23
|
||||
/homeassistant/components/bluemaestro/ @bdraco
|
||||
/tests/components/bluemaestro/ @bdraco
|
||||
/homeassistant/components/blueprint/ @home-assistant/core
|
||||
@@ -945,6 +945,8 @@ CLAUDE.md @home-assistant/core
|
||||
/tests/components/knx/ @Julius2342 @farmio @marvin-w
|
||||
/homeassistant/components/kodi/ @OnFreund
|
||||
/tests/components/kodi/ @OnFreund
|
||||
/homeassistant/components/konnected/ @heythisisnate
|
||||
/tests/components/konnected/ @heythisisnate
|
||||
/homeassistant/components/kostal_plenticore/ @stegm
|
||||
/tests/components/kostal_plenticore/ @stegm
|
||||
/homeassistant/components/kraken/ @eifinger
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
"""Support for Abode Security System alarm control panels."""
|
||||
|
||||
from typing import override
|
||||
|
||||
from jaraco.abode.devices.alarm import Alarm
|
||||
|
||||
from homeassistant.components.alarm_control_panel import (
|
||||
@@ -39,7 +37,6 @@ class AbodeAlarm(AbodeDevice, AlarmControlPanelEntity):
|
||||
)
|
||||
_device: Alarm
|
||||
|
||||
@override
|
||||
@property
|
||||
def alarm_state(self) -> AlarmControlPanelState | None:
|
||||
"""Return the state of the device."""
|
||||
@@ -51,22 +48,18 @@ class AbodeAlarm(AbodeDevice, AlarmControlPanelEntity):
|
||||
return AlarmControlPanelState.ARMED_HOME
|
||||
return None
|
||||
|
||||
@override
|
||||
def alarm_disarm(self, code: str | None = None) -> None:
|
||||
"""Send disarm command."""
|
||||
self._device.set_standby()
|
||||
|
||||
@override
|
||||
def alarm_arm_home(self, code: str | None = None) -> None:
|
||||
"""Send arm home command."""
|
||||
self._device.set_home()
|
||||
|
||||
@override
|
||||
def alarm_arm_away(self, code: str | None = None) -> None:
|
||||
"""Send arm away command."""
|
||||
self._device.set_away()
|
||||
|
||||
@override
|
||||
@property
|
||||
def extra_state_attributes(self) -> dict[str, str]:
|
||||
"""Return the state attributes."""
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Support for Abode Security System binary sensors."""
|
||||
|
||||
from typing import cast, override
|
||||
from typing import cast
|
||||
|
||||
from jaraco.abode.devices.binary_sensor import BinarySensor
|
||||
|
||||
@@ -44,13 +44,11 @@ class AbodeBinarySensor(AbodeDevice, BinarySensorEntity):
|
||||
_attr_name = None
|
||||
_device: BinarySensor
|
||||
|
||||
@override
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return True if the binary sensor is on."""
|
||||
return cast(bool, self._device.is_on)
|
||||
|
||||
@override
|
||||
@property
|
||||
def device_class(self) -> BinarySensorDeviceClass | None:
|
||||
"""Return the class of the binary sensor."""
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Support for Abode Security System cameras."""
|
||||
|
||||
from datetime import timedelta
|
||||
from typing import Any, cast, override
|
||||
from typing import Any, cast
|
||||
|
||||
from jaraco.abode.devices.base import Device
|
||||
from jaraco.abode.devices.camera import Camera as AbodeCam
|
||||
@@ -49,7 +49,6 @@ class AbodeCamera(AbodeDevice, Camera):
|
||||
self._event = event
|
||||
self._response: Response | None = None
|
||||
|
||||
@override
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Subscribe Abode events."""
|
||||
await super().async_added_to_hass()
|
||||
@@ -88,7 +87,6 @@ class AbodeCamera(AbodeDevice, Camera):
|
||||
else:
|
||||
self._response = None
|
||||
|
||||
@override
|
||||
def camera_image(
|
||||
self, width: int | None = None, height: int | None = None
|
||||
) -> bytes | None:
|
||||
@@ -100,12 +98,10 @@ class AbodeCamera(AbodeDevice, Camera):
|
||||
|
||||
return None
|
||||
|
||||
@override
|
||||
def turn_on(self) -> None:
|
||||
"""Turn on camera."""
|
||||
self._device.privacy_mode(False)
|
||||
|
||||
@override
|
||||
def turn_off(self) -> None:
|
||||
"""Turn off camera."""
|
||||
self._device.privacy_mode(True)
|
||||
@@ -116,7 +112,6 @@ class AbodeCamera(AbodeDevice, Camera):
|
||||
self.get_image()
|
||||
self.schedule_update_ha_state()
|
||||
|
||||
@override
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return true if on."""
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from collections.abc import Mapping
|
||||
from http import HTTPStatus
|
||||
from typing import Any, cast, override
|
||||
from typing import Any, cast
|
||||
|
||||
from jaraco.abode.client import Client as Abode
|
||||
from jaraco.abode.exceptions import (
|
||||
@@ -106,7 +106,6 @@ class AbodeFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
title=cast(str, self._username), data=config_data
|
||||
)
|
||||
|
||||
@override
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Support for Abode Security System covers."""
|
||||
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from jaraco.abode.devices.cover import Cover
|
||||
|
||||
@@ -32,18 +32,15 @@ class AbodeCover(AbodeDevice, CoverEntity):
|
||||
_device: Cover
|
||||
_attr_name = None
|
||||
|
||||
@override
|
||||
@property
|
||||
def is_closed(self) -> bool:
|
||||
"""Return true if cover is closed, else False."""
|
||||
return not self._device.is_open
|
||||
|
||||
@override
|
||||
def close_cover(self, **kwargs: Any) -> None:
|
||||
"""Issue close command to cover."""
|
||||
self._device.close_cover()
|
||||
|
||||
@override
|
||||
def open_cover(self, **kwargs: Any) -> None:
|
||||
"""Issue open command to cover."""
|
||||
self._device.open_cover()
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
"""Support for Abode Security System entities."""
|
||||
|
||||
from typing import override
|
||||
|
||||
from jaraco.abode.automation import Automation as AbodeAuto
|
||||
from jaraco.abode.devices.base import Device as AbodeDev
|
||||
|
||||
@@ -23,7 +21,6 @@ class AbodeEntity(Entity):
|
||||
self._data = data
|
||||
self._attr_should_poll = data.polling
|
||||
|
||||
@override
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Subscribe to Abode connection status updates."""
|
||||
await self.hass.async_add_executor_job(
|
||||
@@ -34,7 +31,6 @@ class AbodeEntity(Entity):
|
||||
|
||||
self._data.entity_ids.add(self.entity_id)
|
||||
|
||||
@override
|
||||
async def async_will_remove_from_hass(self) -> None:
|
||||
"""Unsubscribe from Abode connection status updates."""
|
||||
await self.hass.async_add_executor_job(
|
||||
@@ -56,7 +52,6 @@ class AbodeDevice(AbodeEntity):
|
||||
self._device = device
|
||||
self._attr_unique_id = device.uuid
|
||||
|
||||
@override
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Subscribe to device events."""
|
||||
await super().async_added_to_hass()
|
||||
@@ -66,7 +61,6 @@ class AbodeDevice(AbodeEntity):
|
||||
self._update_callback,
|
||||
)
|
||||
|
||||
@override
|
||||
async def async_will_remove_from_hass(self) -> None:
|
||||
"""Unsubscribe from device events."""
|
||||
await super().async_will_remove_from_hass()
|
||||
@@ -78,7 +72,6 @@ class AbodeDevice(AbodeEntity):
|
||||
"""Update device state."""
|
||||
self._device.refresh()
|
||||
|
||||
@override
|
||||
@property
|
||||
def extra_state_attributes(self) -> dict[str, str]:
|
||||
"""Return the state attributes."""
|
||||
@@ -89,7 +82,6 @@ class AbodeDevice(AbodeEntity):
|
||||
"device_type": self._device.type,
|
||||
}
|
||||
|
||||
@override
|
||||
@property
|
||||
def device_info(self) -> DeviceInfo:
|
||||
"""Return device registry information for this entity."""
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Support for Abode Security System lights."""
|
||||
|
||||
from math import ceil
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from jaraco.abode.devices.light import Light
|
||||
|
||||
@@ -43,7 +43,6 @@ class AbodeLight(AbodeDevice, LightEntity):
|
||||
_attr_max_color_temp_kelvin = DEFAULT_MAX_KELVIN
|
||||
_attr_min_color_temp_kelvin = DEFAULT_MIN_KELVIN
|
||||
|
||||
@override
|
||||
def turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn on the light."""
|
||||
if ATTR_COLOR_TEMP_KELVIN in kwargs and self._device.is_color_capable:
|
||||
@@ -62,18 +61,15 @@ class AbodeLight(AbodeDevice, LightEntity):
|
||||
|
||||
self._device.switch_on()
|
||||
|
||||
@override
|
||||
def turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn off the light."""
|
||||
self._device.switch_off()
|
||||
|
||||
@override
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return true if device is on."""
|
||||
return bool(self._device.is_on)
|
||||
|
||||
@override
|
||||
@property
|
||||
def brightness(self) -> int | None:
|
||||
"""Return the brightness of the light."""
|
||||
@@ -84,7 +80,6 @@ class AbodeLight(AbodeDevice, LightEntity):
|
||||
return 255 if brightness == 100 else ceil(brightness * 255 / 99.0)
|
||||
return None
|
||||
|
||||
@override
|
||||
@property
|
||||
def color_temp_kelvin(self) -> int | None:
|
||||
"""Return the color temp of the light."""
|
||||
@@ -92,7 +87,6 @@ class AbodeLight(AbodeDevice, LightEntity):
|
||||
return int(self._device.color_temp)
|
||||
return None
|
||||
|
||||
@override
|
||||
@property
|
||||
def hs_color(self) -> tuple[float, float] | None:
|
||||
"""Return the color of the light."""
|
||||
@@ -101,7 +95,6 @@ class AbodeLight(AbodeDevice, LightEntity):
|
||||
_hs = self._device.color
|
||||
return _hs
|
||||
|
||||
@override
|
||||
@property
|
||||
def color_mode(self) -> ColorMode:
|
||||
"""Return the color mode of the light."""
|
||||
@@ -113,7 +106,6 @@ class AbodeLight(AbodeDevice, LightEntity):
|
||||
return ColorMode.BRIGHTNESS
|
||||
return ColorMode.ONOFF
|
||||
|
||||
@override
|
||||
@property
|
||||
def supported_color_modes(self) -> set[ColorMode]:
|
||||
"""Flag supported color modes."""
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Support for the Abode Security System locks."""
|
||||
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from jaraco.abode.devices.lock import Lock
|
||||
|
||||
@@ -32,17 +32,14 @@ class AbodeLock(AbodeDevice, LockEntity):
|
||||
_device: Lock
|
||||
_attr_name = None
|
||||
|
||||
@override
|
||||
def lock(self, **kwargs: Any) -> None:
|
||||
"""Lock the device."""
|
||||
self._device.lock()
|
||||
|
||||
@override
|
||||
def unlock(self, **kwargs: Any) -> None:
|
||||
"""Unlock the device."""
|
||||
self._device.unlock()
|
||||
|
||||
@override
|
||||
@property
|
||||
def is_locked(self) -> bool:
|
||||
"""Return true if device is on."""
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import cast, override
|
||||
from typing import cast
|
||||
|
||||
from jaraco.abode.devices.sensor import Sensor
|
||||
|
||||
@@ -93,13 +93,11 @@ class AbodeSensor(AbodeDevice, SensorEntity):
|
||||
self.entity_description = description
|
||||
self._attr_unique_id = f"{device.uuid}-{description.key}"
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_value(self) -> float:
|
||||
"""Return the state of the sensor."""
|
||||
return self.entity_description.value_fn(self._device)
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_unit_of_measurement(self) -> str:
|
||||
"""Return the native unit of measurement."""
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Support for Abode Security System switches."""
|
||||
|
||||
from typing import Any, cast, override
|
||||
from typing import Any, cast
|
||||
|
||||
from jaraco.abode.devices.switch import Switch
|
||||
|
||||
@@ -43,17 +43,14 @@ class AbodeSwitch(AbodeDevice, SwitchEntity):
|
||||
_device: Switch
|
||||
_attr_name = None
|
||||
|
||||
@override
|
||||
def turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn on the device."""
|
||||
self._device.switch_on()
|
||||
|
||||
@override
|
||||
def turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn off the device."""
|
||||
self._device.switch_off()
|
||||
|
||||
@override
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return true if device is on."""
|
||||
@@ -65,7 +62,6 @@ class AbodeAutomationSwitch(AbodeAutomation, SwitchEntity):
|
||||
|
||||
_attr_translation_key = "automation"
|
||||
|
||||
@override
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Set up trigger automation service."""
|
||||
await super().async_added_to_hass()
|
||||
@@ -73,13 +69,11 @@ class AbodeAutomationSwitch(AbodeAutomation, SwitchEntity):
|
||||
signal = f"abode_trigger_automation_{self.entity_id}"
|
||||
self.async_on_remove(async_dispatcher_connect(self.hass, signal, self.trigger))
|
||||
|
||||
@override
|
||||
def turn_on(self, **kwargs: Any) -> None:
|
||||
"""Enable the automation."""
|
||||
if self._automation.enable(True):
|
||||
self.schedule_update_ha_state()
|
||||
|
||||
@override
|
||||
def turn_off(self, **kwargs: Any) -> None:
|
||||
"""Disable the automation."""
|
||||
if self._automation.enable(False):
|
||||
@@ -89,7 +83,6 @@ class AbodeAutomationSwitch(AbodeAutomation, SwitchEntity):
|
||||
"""Trigger the automation."""
|
||||
self._automation.trigger()
|
||||
|
||||
@override
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return True if the automation is enabled."""
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import override
|
||||
|
||||
from aioacaia.acaiascale import AcaiaScale
|
||||
|
||||
@@ -56,7 +55,6 @@ class AcaiaBinarySensor(AcaiaEntity, BinarySensorEntity):
|
||||
|
||||
entity_description: AcaiaBinarySensorEntityDescription
|
||||
|
||||
@override
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return true if the binary sensor is on."""
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from collections.abc import Callable, Coroutine
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from aioacaia.acaiascale import AcaiaScale
|
||||
|
||||
@@ -58,7 +58,6 @@ class AcaiaButton(AcaiaEntity, ButtonEntity):
|
||||
|
||||
entity_description: AcaiaButtonEntityDescription
|
||||
|
||||
@override
|
||||
async def async_press(self) -> None:
|
||||
"""Handle the button press."""
|
||||
await self.entity_description.press_fn(self._scale)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Config flow for Acaia integration."""
|
||||
|
||||
import logging
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from aioacaia.exceptions import AcaiaDeviceNotFound, AcaiaError, AcaiaUnknownDevice
|
||||
from aioacaia.helpers import is_new_scale
|
||||
@@ -34,7 +34,6 @@ class AcaiaConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
self._discovered: dict[str, Any] = {}
|
||||
self._discovered_devices: dict[str, str] = {}
|
||||
|
||||
@override
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
@@ -95,7 +94,6 @@ class AcaiaConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
errors=errors,
|
||||
)
|
||||
|
||||
@override
|
||||
async def async_step_bluetooth(
|
||||
self, discovery_info: BluetoothServiceInfoBleak
|
||||
) -> ConfigFlowResult:
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
from typing import override
|
||||
|
||||
from aioacaia.acaiascale import AcaiaScale
|
||||
from aioacaia.exceptions import AcaiaDeviceNotFound, AcaiaError
|
||||
@@ -60,7 +59,6 @@ class AcaiaCoordinator(DataUpdateCoordinator[None]):
|
||||
"""Return the scale object."""
|
||||
return self._scale
|
||||
|
||||
@override
|
||||
async def _async_update_data(self) -> None:
|
||||
"""Fetch data."""
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"""Base class for Acaia entities."""
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import override
|
||||
|
||||
from homeassistant.helpers.device_registry import (
|
||||
CONNECTION_BLUETOOTH,
|
||||
@@ -41,7 +40,6 @@ class AcaiaEntity(CoordinatorEntity[AcaiaCoordinator]):
|
||||
connections={(CONNECTION_BLUETOOTH, self._scale.mac)},
|
||||
)
|
||||
|
||||
@override
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
"""Returns whether entity is available."""
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import override
|
||||
|
||||
from aioacaia.acaiascale import AcaiaDeviceState, AcaiaScale
|
||||
from aioacaia.const import UnitMass as AcaiaUnitOfMass
|
||||
@@ -98,7 +97,6 @@ class AcaiaSensor(AcaiaEntity, SensorEntity):
|
||||
|
||||
entity_description: AcaiaDynamicUnitSensorEntityDescription
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_unit_of_measurement(self) -> str | None:
|
||||
"""Return the unit of measurement of this entity."""
|
||||
@@ -109,7 +107,6 @@ class AcaiaSensor(AcaiaEntity, SensorEntity):
|
||||
return self.entity_description.unit_fn(self._scale.device_state)
|
||||
return self.entity_description.native_unit_of_measurement
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_value(self) -> int | float | None:
|
||||
"""Return the state of the entity."""
|
||||
@@ -122,7 +119,6 @@ class AcaiaRestoreSensor(AcaiaEntity, RestoreSensor):
|
||||
entity_description: AcaiaSensorEntityDescription
|
||||
_restored_data: SensorExtraStoredData | None = None
|
||||
|
||||
@override
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Handle entity which will be added."""
|
||||
await super().async_added_to_hass()
|
||||
@@ -137,7 +133,6 @@ class AcaiaRestoreSensor(AcaiaEntity, RestoreSensor):
|
||||
if self._scale.device_state is not None:
|
||||
self._attr_native_value = self.entity_description.value_fn(self._scale)
|
||||
|
||||
@override
|
||||
@callback
|
||||
def _handle_coordinator_update(self) -> None:
|
||||
"""Handle updated data from the coordinator."""
|
||||
@@ -145,7 +140,6 @@ class AcaiaRestoreSensor(AcaiaEntity, RestoreSensor):
|
||||
self._attr_native_value = self.entity_description.value_fn(self._scale)
|
||||
self._async_write_ha_state()
|
||||
|
||||
@override
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
"""Return True if entity is available."""
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from asyncio import timeout
|
||||
from collections.abc import Mapping
|
||||
from typing import TYPE_CHECKING, Any, override
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from accuweather import AccuWeather, ApiError, InvalidApiKeyError, RequestsExceededError
|
||||
from aiohttp import ClientError
|
||||
@@ -24,7 +24,6 @@ class AccuWeatherFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
_latitude: float | None = None
|
||||
_longitude: float | None = None
|
||||
|
||||
@override
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
|
||||
@@ -5,7 +5,7 @@ from collections.abc import Awaitable, Callable
|
||||
from dataclasses import dataclass
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
from typing import TYPE_CHECKING, Any, override
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from accuweather import AccuWeather, ApiError, InvalidApiKeyError, RequestsExceededError
|
||||
from aiohttp.client_exceptions import ClientConnectorError
|
||||
@@ -77,7 +77,6 @@ class AccuWeatherObservationDataUpdateCoordinator(
|
||||
update_interval=UPDATE_INTERVAL_OBSERVATION,
|
||||
)
|
||||
|
||||
@override
|
||||
async def _async_update_data(self) -> dict[str, Any]:
|
||||
"""Update data via library."""
|
||||
try:
|
||||
@@ -136,7 +135,6 @@ class AccuWeatherForecastDataUpdateCoordinator(
|
||||
update_interval=update_interval,
|
||||
)
|
||||
|
||||
@override
|
||||
async def _async_update_data(self) -> list[dict[str, Any]]:
|
||||
"""Update forecast data via library."""
|
||||
try:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, cast, override
|
||||
from typing import Any, cast
|
||||
|
||||
from homeassistant.components.sensor import (
|
||||
SensorDeviceClass,
|
||||
@@ -434,19 +434,16 @@ class AccuWeatherSensor(
|
||||
self._attr_unique_id = f"{coordinator.location_key}-{description.key}".lower()
|
||||
self._attr_device_info = coordinator.device_info
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_value(self) -> str | int | float | None:
|
||||
"""Return the state."""
|
||||
return self.entity_description.value_fn(self._sensor_data)
|
||||
|
||||
@override
|
||||
@property
|
||||
def extra_state_attributes(self) -> dict[str, Any]:
|
||||
"""Return the state attributes."""
|
||||
return self.entity_description.attr_fn(self.coordinator.data)
|
||||
|
||||
@override
|
||||
@callback
|
||||
def _handle_coordinator_update(self) -> None:
|
||||
"""Handle data update."""
|
||||
@@ -496,19 +493,16 @@ class AccuWeatherForecastSensor(
|
||||
self._attr_translation_placeholders = {"forecast_day": str(forecast_day)}
|
||||
self.forecast_day = forecast_day
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_value(self) -> str | int | float | None:
|
||||
"""Return the state."""
|
||||
return self.entity_description.value_fn(self._sensor_data)
|
||||
|
||||
@override
|
||||
@property
|
||||
def extra_state_attributes(self) -> dict[str, Any]:
|
||||
"""Return the state attributes."""
|
||||
return self.entity_description.attr_fn(self._sensor_data)
|
||||
|
||||
@override
|
||||
@callback
|
||||
def _handle_coordinator_update(self) -> None:
|
||||
"""Handle data update."""
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Support for the AccuWeather service."""
|
||||
|
||||
from typing import cast, override
|
||||
from typing import cast
|
||||
|
||||
from homeassistant.components.weather import (
|
||||
ATTR_FORECAST_CLOUD_COVERAGE,
|
||||
@@ -95,19 +95,16 @@ class AccuWeatherEntity(
|
||||
self.daily_coordinator = accuweather_data.coordinator_daily_forecast
|
||||
self.hourly_coordinator = accuweather_data.coordinator_hourly_forecast
|
||||
|
||||
@override
|
||||
@property
|
||||
def condition(self) -> str | None:
|
||||
"""Return the current condition."""
|
||||
return CONDITION_MAP.get(self.observation_coordinator.data["WeatherIcon"])
|
||||
|
||||
@override
|
||||
@property
|
||||
def cloud_coverage(self) -> float:
|
||||
"""Return the Cloud coverage in %."""
|
||||
return cast(float, self.observation_coordinator.data["CloudCover"])
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_apparent_temperature(self) -> float:
|
||||
"""Return the apparent temperature."""
|
||||
@@ -118,7 +115,6 @@ class AccuWeatherEntity(
|
||||
],
|
||||
)
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_temperature(self) -> float:
|
||||
"""Return the temperature."""
|
||||
@@ -127,7 +123,6 @@ class AccuWeatherEntity(
|
||||
self.observation_coordinator.data["Temperature"][API_METRIC][ATTR_VALUE],
|
||||
)
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_pressure(self) -> float:
|
||||
"""Return the pressure."""
|
||||
@@ -135,7 +130,6 @@ class AccuWeatherEntity(
|
||||
float, self.observation_coordinator.data["Pressure"][API_METRIC][ATTR_VALUE]
|
||||
)
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_dew_point(self) -> float:
|
||||
"""Return the dew point."""
|
||||
@@ -143,13 +137,11 @@ class AccuWeatherEntity(
|
||||
float, self.observation_coordinator.data["DewPoint"][API_METRIC][ATTR_VALUE]
|
||||
)
|
||||
|
||||
@override
|
||||
@property
|
||||
def humidity(self) -> int:
|
||||
"""Return the humidity."""
|
||||
return cast(int, self.observation_coordinator.data["RelativeHumidity"])
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_wind_gust_speed(self) -> float:
|
||||
"""Return the wind gust speed."""
|
||||
@@ -160,7 +152,6 @@ class AccuWeatherEntity(
|
||||
],
|
||||
)
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_wind_speed(self) -> float:
|
||||
"""Return the wind speed."""
|
||||
@@ -171,7 +162,6 @@ class AccuWeatherEntity(
|
||||
],
|
||||
)
|
||||
|
||||
@override
|
||||
@property
|
||||
def wind_bearing(self) -> int:
|
||||
"""Return the wind bearing."""
|
||||
@@ -179,7 +169,6 @@ class AccuWeatherEntity(
|
||||
int, self.observation_coordinator.data["Wind"][ATTR_DIRECTION]["Degrees"]
|
||||
)
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_visibility(self) -> float:
|
||||
"""Return the visibility."""
|
||||
@@ -188,13 +177,11 @@ class AccuWeatherEntity(
|
||||
self.observation_coordinator.data["Visibility"][API_METRIC][ATTR_VALUE],
|
||||
)
|
||||
|
||||
@override
|
||||
@property
|
||||
def uv_index(self) -> float:
|
||||
"""Return the UV index."""
|
||||
return cast(float, self.observation_coordinator.data["UVIndex"])
|
||||
|
||||
@override
|
||||
@callback
|
||||
def _async_forecast_daily(self) -> list[Forecast] | None:
|
||||
"""Return the daily forecast in native units."""
|
||||
@@ -225,7 +212,6 @@ class AccuWeatherEntity(
|
||||
for item in self.daily_coordinator.data
|
||||
]
|
||||
|
||||
@override
|
||||
@callback
|
||||
def _async_forecast_hourly(self) -> list[Forecast] | None:
|
||||
"""Return the hourly forecast in native units."""
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import logging
|
||||
import re
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from serialx import Serial, SerialException
|
||||
import voluptuous as vol
|
||||
@@ -140,14 +140,12 @@ class AcerSwitch(SwitchEntity):
|
||||
self._attributes[key] = awns
|
||||
self._attr_extra_state_attributes = self._attributes
|
||||
|
||||
@override
|
||||
def turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn the projector on."""
|
||||
msg = CMD_DICT[STATE_ON]
|
||||
self._write_read(msg)
|
||||
self._attr_is_on = True
|
||||
|
||||
@override
|
||||
def turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn the projector off."""
|
||||
msg = CMD_DICT[STATE_OFF]
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from asyncio import timeout
|
||||
from contextlib import suppress
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
import aiopulse
|
||||
import voluptuous as vol
|
||||
@@ -22,7 +22,6 @@ class AcmedaFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
"""Initialize the config flow."""
|
||||
self.discovered_hubs: dict[str, aiopulse.Hub] | None = None
|
||||
|
||||
@override
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Support for Acmeda Roller Blinds."""
|
||||
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.components.cover import (
|
||||
ATTR_POSITION,
|
||||
@@ -47,7 +47,6 @@ class AcmedaCover(AcmedaEntity, CoverEntity):
|
||||
|
||||
_attr_name = None
|
||||
|
||||
@override
|
||||
@property
|
||||
def current_cover_position(self) -> int | None:
|
||||
"""Return the current position of the roller blind.
|
||||
@@ -59,7 +58,6 @@ class AcmedaCover(AcmedaEntity, CoverEntity):
|
||||
position = 100 - self.roller.closed_percent
|
||||
return position
|
||||
|
||||
@override
|
||||
@property
|
||||
def current_cover_tilt_position(self) -> int | None:
|
||||
"""Return the current tilt of the roller blind.
|
||||
@@ -71,7 +69,6 @@ class AcmedaCover(AcmedaEntity, CoverEntity):
|
||||
position = 100 - self.roller.closed_percent
|
||||
return position
|
||||
|
||||
@override
|
||||
@property
|
||||
def supported_features(self) -> CoverEntityFeature:
|
||||
"""Flag supported features."""
|
||||
@@ -93,48 +90,39 @@ class AcmedaCover(AcmedaEntity, CoverEntity):
|
||||
|
||||
return supported_features
|
||||
|
||||
@override
|
||||
@property
|
||||
def is_closed(self) -> bool:
|
||||
"""Return if the cover is closed."""
|
||||
return self.roller.closed_percent == 100 # type: ignore[no-any-return]
|
||||
|
||||
@override
|
||||
async def async_close_cover(self, **kwargs: Any) -> None:
|
||||
"""Close the roller."""
|
||||
await self.roller.move_down()
|
||||
|
||||
@override
|
||||
async def async_open_cover(self, **kwargs: Any) -> None:
|
||||
"""Open the roller."""
|
||||
await self.roller.move_up()
|
||||
|
||||
@override
|
||||
async def async_stop_cover(self, **kwargs: Any) -> None:
|
||||
"""Stop the roller."""
|
||||
await self.roller.move_stop()
|
||||
|
||||
@override
|
||||
async def async_set_cover_position(self, **kwargs: Any) -> None:
|
||||
"""Move the roller shutter to a specific position."""
|
||||
await self.roller.move_to(100 - kwargs[ATTR_POSITION])
|
||||
|
||||
@override
|
||||
async def async_close_cover_tilt(self, **kwargs: Any) -> None:
|
||||
"""Close the roller."""
|
||||
await self.roller.move_down()
|
||||
|
||||
@override
|
||||
async def async_open_cover_tilt(self, **kwargs: Any) -> None:
|
||||
"""Open the roller."""
|
||||
await self.roller.move_up()
|
||||
|
||||
@override
|
||||
async def async_stop_cover_tilt(self, **kwargs: Any) -> None:
|
||||
"""Stop the roller."""
|
||||
await self.roller.move_stop()
|
||||
|
||||
@override
|
||||
async def async_set_cover_tilt_position(self, **kwargs: Any) -> None:
|
||||
"""Tilt the roller shutter to a specific position."""
|
||||
await self.roller.move_to(100 - kwargs[ATTR_POSITION])
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
"""Base class for Acmeda Roller Blinds."""
|
||||
|
||||
from typing import override
|
||||
|
||||
import aiopulse
|
||||
|
||||
from homeassistant.core import callback
|
||||
@@ -42,7 +40,6 @@ class AcmedaEntity(entity.Entity):
|
||||
|
||||
await self.async_remove(force_remove=True)
|
||||
|
||||
@override
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Entity has been added to hass."""
|
||||
self.roller.callback_subscribe(self.notify_update)
|
||||
@@ -55,7 +52,6 @@ class AcmedaEntity(entity.Entity):
|
||||
)
|
||||
)
|
||||
|
||||
@override
|
||||
async def async_will_remove_from_hass(self) -> None:
|
||||
"""Entity being removed from hass."""
|
||||
self.roller.callback_unsubscribe(self.notify_update)
|
||||
@@ -66,7 +62,6 @@ class AcmedaEntity(entity.Entity):
|
||||
LOGGER.debug("Device update notification received: %s", self.name)
|
||||
self.async_write_ha_state()
|
||||
|
||||
@override
|
||||
@property
|
||||
def unique_id(self) -> str:
|
||||
"""Return the unique ID of this roller."""
|
||||
@@ -77,7 +72,6 @@ class AcmedaEntity(entity.Entity):
|
||||
"""Return the ID of this roller."""
|
||||
return self.roller.id # type: ignore[no-any-return]
|
||||
|
||||
@override
|
||||
@property
|
||||
def device_info(self) -> dr.DeviceInfo:
|
||||
"""Return the device info."""
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
"""Support for Acmeda Roller Blind Batteries."""
|
||||
|
||||
from typing import override
|
||||
|
||||
from homeassistant.components.sensor import SensorDeviceClass, SensorEntity
|
||||
from homeassistant.const import PERCENTAGE
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
@@ -45,7 +43,6 @@ class AcmedaBattery(AcmedaEntity, SensorEntity):
|
||||
_attr_device_class = SensorDeviceClass.BATTERY
|
||||
_attr_native_unit_of_measurement = PERCENTAGE
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_value(self) -> float | int | None:
|
||||
"""Return the state of the device."""
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Support for Actiontec MI424WR (Verizon FIOS) routers."""
|
||||
|
||||
import logging
|
||||
from typing import Final, override
|
||||
from typing import Final
|
||||
|
||||
import telnetlib # pylint: disable=deprecated-module
|
||||
import voluptuous as vol
|
||||
@@ -50,13 +50,11 @@ class ActiontecDeviceScanner(DeviceScanner):
|
||||
data = self.get_actiontec_data()
|
||||
self.success_init = data is not None
|
||||
|
||||
@override
|
||||
def scan_devices(self) -> list[str]:
|
||||
"""Scan for new devices and return a list with found device IDs."""
|
||||
self._update_info()
|
||||
return [client.mac_address for client in self.last_results]
|
||||
|
||||
@override
|
||||
def get_device_name(self, device: str) -> str | None:
|
||||
"""Return the name of the given device or None if we don't know."""
|
||||
for client in self.last_results:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Climate platform for Actron Air integration."""
|
||||
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from actron_neo_api import ActronAirStatus, ActronAirZone
|
||||
|
||||
@@ -93,7 +93,6 @@ class ActronSystemClimate(ActronAirAcEntity, ActronAirClimateEntity):
|
||||
super().__init__(coordinator)
|
||||
self._attr_unique_id = self._serial_number
|
||||
|
||||
@override
|
||||
@property
|
||||
def hvac_modes(self) -> list[HVACMode]:
|
||||
"""Return the list of supported HVAC modes."""
|
||||
@@ -105,13 +104,11 @@ class ActronSystemClimate(ActronAirAcEntity, ActronAirClimateEntity):
|
||||
modes.append(HVACMode.OFF)
|
||||
return modes
|
||||
|
||||
@override
|
||||
@property
|
||||
def min_temp(self) -> float:
|
||||
"""Return the minimum temperature that can be set."""
|
||||
return self._status.min_temp
|
||||
|
||||
@override
|
||||
@property
|
||||
def max_temp(self) -> float:
|
||||
"""Return the maximum temperature that can be set."""
|
||||
@@ -122,7 +119,6 @@ class ActronSystemClimate(ActronAirAcEntity, ActronAirClimateEntity):
|
||||
"""Get the current status from the coordinator."""
|
||||
return self.coordinator.data
|
||||
|
||||
@override
|
||||
@property
|
||||
def hvac_mode(self) -> HVACMode | None:
|
||||
"""Return the current HVAC mode."""
|
||||
@@ -132,46 +128,39 @@ class ActronSystemClimate(ActronAirAcEntity, ActronAirClimateEntity):
|
||||
mode = self._status.user_aircon_settings.mode
|
||||
return HVAC_MODE_MAPPING_ACTRONAIR_TO_HA.get(mode)
|
||||
|
||||
@override
|
||||
@property
|
||||
def fan_mode(self) -> str | None:
|
||||
"""Return the current fan mode."""
|
||||
fan_mode = self._status.user_aircon_settings.base_fan_mode
|
||||
return FAN_MODE_MAPPING_ACTRONAIR_TO_HA.get(fan_mode)
|
||||
|
||||
@override
|
||||
@property
|
||||
def current_humidity(self) -> float:
|
||||
"""Return the current humidity."""
|
||||
return self._status.master_info.live_humidity_pc
|
||||
|
||||
@override
|
||||
@property
|
||||
def current_temperature(self) -> float:
|
||||
"""Return the current temperature."""
|
||||
return self._status.master_info.live_temp_c
|
||||
|
||||
@override
|
||||
@property
|
||||
def target_temperature(self) -> float:
|
||||
"""Return the target temperature."""
|
||||
return self._status.user_aircon_settings.current_setpoint
|
||||
|
||||
@override
|
||||
@actron_air_command
|
||||
async def async_set_fan_mode(self, fan_mode: str) -> None:
|
||||
"""Set a new fan mode."""
|
||||
api_fan_mode = FAN_MODE_MAPPING_HA_TO_ACTRONAIR[fan_mode]
|
||||
await self._status.user_aircon_settings.set_fan_mode(api_fan_mode)
|
||||
|
||||
@override
|
||||
@actron_air_command
|
||||
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
|
||||
"""Set the HVAC mode."""
|
||||
ac_mode = HVAC_MODE_MAPPING_HA_TO_ACTRONAIR[hvac_mode]
|
||||
await self._status.ac_system.set_system_mode(ac_mode)
|
||||
|
||||
@override
|
||||
@actron_air_command
|
||||
async def async_set_temperature(self, **kwargs: Any) -> None:
|
||||
"""Set the temperature."""
|
||||
@@ -201,7 +190,6 @@ class ActronZoneClimate(ActronAirZoneEntity, ActronAirClimateEntity):
|
||||
super().__init__(coordinator, zone)
|
||||
self._attr_unique_id: str = self._zone_identifier
|
||||
|
||||
@override
|
||||
@property
|
||||
def hvac_modes(self) -> list[HVACMode]:
|
||||
"""Return the list of supported HVAC modes."""
|
||||
@@ -214,13 +202,11 @@ class ActronZoneClimate(ActronAirZoneEntity, ActronAirClimateEntity):
|
||||
modes.append(HVACMode.OFF)
|
||||
return modes
|
||||
|
||||
@override
|
||||
@property
|
||||
def min_temp(self) -> float:
|
||||
"""Return the minimum temperature that can be set."""
|
||||
return self._zone.min_temp
|
||||
|
||||
@override
|
||||
@property
|
||||
def max_temp(self) -> float:
|
||||
"""Return the maximum temperature that can be set."""
|
||||
@@ -232,7 +218,6 @@ class ActronZoneClimate(ActronAirZoneEntity, ActronAirClimateEntity):
|
||||
status = self.coordinator.data
|
||||
return status.zones[self._zone_id]
|
||||
|
||||
@override
|
||||
@property
|
||||
def hvac_mode(self) -> HVACMode | None:
|
||||
"""Return the current HVAC mode."""
|
||||
@@ -241,32 +226,27 @@ class ActronZoneClimate(ActronAirZoneEntity, ActronAirClimateEntity):
|
||||
return HVAC_MODE_MAPPING_ACTRONAIR_TO_HA.get(mode)
|
||||
return HVACMode.OFF
|
||||
|
||||
@override
|
||||
@property
|
||||
def current_humidity(self) -> float | None:
|
||||
"""Return the current humidity."""
|
||||
return self._zone.humidity
|
||||
|
||||
@override
|
||||
@property
|
||||
def current_temperature(self) -> float | None:
|
||||
"""Return the current temperature."""
|
||||
return self._zone.live_temp_c
|
||||
|
||||
@override
|
||||
@property
|
||||
def target_temperature(self) -> float | None:
|
||||
"""Return the target temperature."""
|
||||
return self._zone.current_setpoint
|
||||
|
||||
@override
|
||||
@actron_air_command
|
||||
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
|
||||
"""Set the HVAC mode."""
|
||||
is_enabled = hvac_mode != HVACMode.OFF
|
||||
await self._zone.enable(is_enabled)
|
||||
|
||||
@override
|
||||
@actron_air_command
|
||||
async def async_set_temperature(self, **kwargs: Any) -> None:
|
||||
"""Set the temperature."""
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import asyncio
|
||||
from collections.abc import Mapping
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from actron_neo_api import ActronAirAPI, ActronAirAuthError
|
||||
|
||||
@@ -30,7 +30,6 @@ class ActronAirConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
self._expires_minutes: str = "30"
|
||||
self.login_task: asyncio.Task[None] | None = None
|
||||
|
||||
@override
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
from dataclasses import dataclass
|
||||
from datetime import timedelta
|
||||
from typing import override
|
||||
|
||||
from actron_neo_api import (
|
||||
ActronAirAPI,
|
||||
@@ -61,7 +60,6 @@ class ActronAirSystemCoordinator(DataUpdateCoordinator[ActronAirStatus]):
|
||||
self.status = self.api.state_manager.get_status(self.serial_number)
|
||||
self.last_seen = dt_util.utcnow()
|
||||
|
||||
@override
|
||||
async def _async_update_data(self) -> ActronAirStatus:
|
||||
"""Fetch updates and merge incremental changes into the full state."""
|
||||
try:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from collections.abc import Callable, Coroutine
|
||||
from functools import wraps
|
||||
from typing import Any, Concatenate, override
|
||||
from typing import Any, Concatenate
|
||||
|
||||
from actron_neo_api import ActronAirAPIError, ActronAirZone
|
||||
|
||||
@@ -49,7 +49,6 @@ class ActronAirEntity(CoordinatorEntity[ActronAirSystemCoordinator]):
|
||||
super().__init__(coordinator)
|
||||
self._serial_number = coordinator.serial_number
|
||||
|
||||
@override
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
"""Return True if entity is available."""
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from collections.abc import Awaitable, Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.components.switch import SwitchEntity, SwitchEntityDescription
|
||||
from homeassistant.const import EntityCategory
|
||||
@@ -100,19 +100,16 @@ class ActronAirSwitch(ActronAirAcEntity, SwitchEntity):
|
||||
self.entity_description = description
|
||||
self._attr_unique_id = f"{coordinator.serial_number}_{description.key}"
|
||||
|
||||
@override
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return true if the switch is on."""
|
||||
return self.entity_description.is_on_fn(self.coordinator)
|
||||
|
||||
@override
|
||||
@actron_air_command
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn the switch on."""
|
||||
await self.entity_description.set_fn(self.coordinator, True)
|
||||
|
||||
@override
|
||||
@actron_air_command
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn the switch off."""
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Support for Adax wifi-enabled home heaters."""
|
||||
|
||||
from typing import Any, cast, override
|
||||
from typing import Any, cast
|
||||
|
||||
from adax import Adax
|
||||
from adax_local import Adax as AdaxLocal
|
||||
@@ -81,7 +81,6 @@ class AdaxDevice(CoordinatorEntity[AdaxCloudCoordinator], ClimateEntity):
|
||||
)
|
||||
self._apply_data(self.room)
|
||||
|
||||
@override
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
"""Whether the entity is available or not."""
|
||||
@@ -92,7 +91,6 @@ class AdaxDevice(CoordinatorEntity[AdaxCloudCoordinator], ClimateEntity):
|
||||
"""Gets the data for this particular device."""
|
||||
return self.coordinator.data[self._device_id]
|
||||
|
||||
@override
|
||||
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
|
||||
"""Set hvac mode."""
|
||||
if hvac_mode == HVACMode.HEAT:
|
||||
@@ -110,7 +108,6 @@ class AdaxDevice(CoordinatorEntity[AdaxCloudCoordinator], ClimateEntity):
|
||||
# Request data refresh from source to verify that update was successful
|
||||
await self.coordinator.async_request_refresh()
|
||||
|
||||
@override
|
||||
async def async_set_temperature(self, **kwargs: Any) -> None:
|
||||
"""Set new target temperature."""
|
||||
if (temperature := kwargs.get(ATTR_TEMPERATURE)) is None:
|
||||
@@ -119,7 +116,6 @@ class AdaxDevice(CoordinatorEntity[AdaxCloudCoordinator], ClimateEntity):
|
||||
self._device_id, temperature, True
|
||||
)
|
||||
|
||||
@override
|
||||
@callback
|
||||
def _handle_coordinator_update(self) -> None:
|
||||
"""Handle updated data from the coordinator."""
|
||||
@@ -165,7 +161,6 @@ class LocalAdaxDevice(CoordinatorEntity[AdaxLocalCoordinator], ClimateEntity):
|
||||
manufacturer="Adax",
|
||||
)
|
||||
|
||||
@override
|
||||
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
|
||||
"""Set hvac mode."""
|
||||
if hvac_mode == HVACMode.HEAT:
|
||||
@@ -184,7 +179,6 @@ class LocalAdaxDevice(CoordinatorEntity[AdaxLocalCoordinator], ClimateEntity):
|
||||
self._attr_hvac_mode = hvac_mode
|
||||
self.async_write_ha_state()
|
||||
|
||||
@override
|
||||
async def async_set_temperature(self, **kwargs: Any) -> None:
|
||||
"""Set new target temperature."""
|
||||
if (temperature := kwargs.get(ATTR_TEMPERATURE)) is None:
|
||||
@@ -216,14 +210,12 @@ class LocalAdaxDevice(CoordinatorEntity[AdaxLocalCoordinator], ClimateEntity):
|
||||
self._attr_icon = "mdi:radiator"
|
||||
self._attr_target_temperature = target_temp
|
||||
|
||||
@override
|
||||
@callback
|
||||
def _handle_coordinator_update(self) -> None:
|
||||
"""Handle updated data from the coordinator."""
|
||||
self._update_hvac_attributes()
|
||||
super()._handle_coordinator_update()
|
||||
|
||||
@override
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""When entity is added to hass."""
|
||||
await super().async_added_to_hass()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Config flow for Adax integration."""
|
||||
|
||||
import logging
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
import adax
|
||||
import adax_local
|
||||
@@ -39,7 +39,6 @@ class AdaxConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
|
||||
VERSION = 2
|
||||
|
||||
@override
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""DataUpdateCoordinator for the Adax component."""
|
||||
|
||||
import logging
|
||||
from typing import Any, cast, override
|
||||
from typing import Any, cast
|
||||
|
||||
from adax import Adax
|
||||
from adax_local import Adax as AdaxLocal
|
||||
@@ -39,7 +39,6 @@ class AdaxCloudCoordinator(DataUpdateCoordinator[dict[str, dict[str, Any]]]):
|
||||
websession=async_get_clientsession(hass),
|
||||
)
|
||||
|
||||
@override
|
||||
async def _async_update_data(self) -> dict[str, dict[str, Any]]:
|
||||
"""Fetch data from the Adax."""
|
||||
try:
|
||||
@@ -88,7 +87,6 @@ class AdaxLocalCoordinator(DataUpdateCoordinator[dict[str, Any] | None]):
|
||||
websession=async_get_clientsession(hass, verify_ssl=False),
|
||||
)
|
||||
|
||||
@override
|
||||
async def _async_update_data(self) -> dict[str, Any]:
|
||||
"""Fetch data from the Adax."""
|
||||
if result := await self.adax_data_handler.get_status():
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Support for Adax energy sensors."""
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import cast, override
|
||||
from typing import cast
|
||||
|
||||
from homeassistant.components.sensor import (
|
||||
SensorDeviceClass,
|
||||
@@ -94,7 +94,6 @@ class AdaxSensor(CoordinatorEntity[AdaxCloudCoordinator], SensorEntity):
|
||||
manufacturer="Adax",
|
||||
)
|
||||
|
||||
@override
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
"""Return True if entity is available."""
|
||||
@@ -104,7 +103,6 @@ class AdaxSensor(CoordinatorEntity[AdaxCloudCoordinator], SensorEntity):
|
||||
in self.coordinator.data[self._device_id]
|
||||
)
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_value(self) -> int | float | None:
|
||||
"""Return the native value of the sensor."""
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Config flow to configure the AdGuard Home integration."""
|
||||
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from adguardhome import AdGuardHome, AdGuardHomeConnectionError
|
||||
import voluptuous as vol
|
||||
@@ -57,7 +57,6 @@ class AdGuardHomeFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
errors=errors or {},
|
||||
)
|
||||
|
||||
@override
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
@@ -103,7 +102,6 @@ class AdGuardHomeFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
},
|
||||
)
|
||||
|
||||
@override
|
||||
async def async_step_hassio(
|
||||
self, discovery_info: HassioServiceInfo
|
||||
) -> ConfigFlowResult:
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
"""AdGuard Home base entity."""
|
||||
|
||||
from typing import override
|
||||
|
||||
from adguardhome import AdGuardHomeError
|
||||
|
||||
from homeassistant.config_entries import SOURCE_HASSIO
|
||||
@@ -48,7 +46,6 @@ class AdGuardHomeEntity(Entity):
|
||||
"""Update AdGuard Home entity."""
|
||||
raise NotImplementedError
|
||||
|
||||
@override
|
||||
@property
|
||||
def device_info(self) -> DeviceInfo:
|
||||
"""Return device information about this AdGuard Home instance."""
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
from collections.abc import Callable, Coroutine
|
||||
from dataclasses import dataclass
|
||||
from datetime import timedelta
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from adguardhome import AdGuardHome
|
||||
|
||||
@@ -118,7 +118,6 @@ class AdGuardHomeSensor(AdGuardHomeEntity, SensorEntity):
|
||||
]
|
||||
)
|
||||
|
||||
@override
|
||||
async def _adguard_update(self) -> None:
|
||||
"""Update AdGuard Home entity."""
|
||||
value = await self.entity_description.value_fn(self.adguard)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
from collections.abc import Callable, Coroutine
|
||||
from dataclasses import dataclass
|
||||
from datetime import timedelta
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from adguardhome import AdGuardHome, AdGuardHomeError
|
||||
|
||||
@@ -113,7 +113,6 @@ class AdGuardHomeSwitch(AdGuardHomeEntity, SwitchEntity):
|
||||
]
|
||||
)
|
||||
|
||||
@override
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn off the switch."""
|
||||
try:
|
||||
@@ -125,7 +124,6 @@ class AdGuardHomeSwitch(AdGuardHomeEntity, SwitchEntity):
|
||||
translation_key="error_while_turn_off",
|
||||
) from err
|
||||
|
||||
@override
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn on the switch."""
|
||||
try:
|
||||
@@ -137,7 +135,6 @@ class AdGuardHomeSwitch(AdGuardHomeEntity, SwitchEntity):
|
||||
translation_key="error_while_turn_on",
|
||||
) from err
|
||||
|
||||
@override
|
||||
async def _adguard_update(self) -> None:
|
||||
"""Update AdGuard Home entity."""
|
||||
self._attr_is_on = await self.entity_description.is_on_fn(self.adguard)()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""AdGuard Home Update platform."""
|
||||
|
||||
from datetime import timedelta
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from adguardhome import AdGuardHomeError
|
||||
|
||||
@@ -50,7 +50,6 @@ class AdGuardHomeUpdate(AdGuardHomeEntity, UpdateEntity):
|
||||
[DOMAIN, self.adguard.host, str(self.adguard.port), "update"]
|
||||
)
|
||||
|
||||
@override
|
||||
async def _adguard_update(self) -> None:
|
||||
"""Update AdGuard Home entity."""
|
||||
value = await self.adguard.update.update_available()
|
||||
@@ -59,7 +58,6 @@ class AdGuardHomeUpdate(AdGuardHomeEntity, UpdateEntity):
|
||||
self._attr_release_summary = value.announcement
|
||||
self._attr_release_url = value.announcement_url
|
||||
|
||||
@override
|
||||
async def async_install(
|
||||
self, version: str | None, backup: bool, **kwargs: Any
|
||||
) -> None:
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
"""Support for ADS binary sensors."""
|
||||
|
||||
from typing import override
|
||||
|
||||
import pyads
|
||||
import voluptuous as vol
|
||||
|
||||
@@ -62,12 +60,10 @@ class AdsBinarySensor(AdsEntity, BinarySensorEntity):
|
||||
super().__init__(ads_hub, name, ads_var)
|
||||
self._attr_device_class = device_class or BinarySensorDeviceClass.MOVING
|
||||
|
||||
@override
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Register device notification."""
|
||||
await self.async_initialize_device(self._ads_var, pyads.PLCTYPE_BOOL)
|
||||
|
||||
@override
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return True if the entity is on."""
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Support for ADS covers."""
|
||||
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
import pyads
|
||||
import voluptuous as vol
|
||||
@@ -122,7 +122,6 @@ class AdsCover(AdsEntity, CoverEntity):
|
||||
if ads_var_pos_set is not None:
|
||||
self._attr_supported_features |= CoverEntityFeature.SET_POSITION
|
||||
|
||||
@override
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Register device notification."""
|
||||
if self._ads_var is not None:
|
||||
@@ -133,7 +132,6 @@ class AdsCover(AdsEntity, CoverEntity):
|
||||
self._ads_var_position, pyads.PLCTYPE_BYTE, STATE_KEY_POSITION
|
||||
)
|
||||
|
||||
@override
|
||||
@property
|
||||
def is_closed(self) -> bool | None:
|
||||
"""Return if the cover is closed."""
|
||||
@@ -143,19 +141,16 @@ class AdsCover(AdsEntity, CoverEntity):
|
||||
return self._state_dict[STATE_KEY_POSITION] == 0
|
||||
return None
|
||||
|
||||
@override
|
||||
@property
|
||||
def current_cover_position(self) -> int:
|
||||
"""Return current position of cover."""
|
||||
return self._state_dict[STATE_KEY_POSITION]
|
||||
|
||||
@override
|
||||
def stop_cover(self, **kwargs: Any) -> None:
|
||||
"""Fire the stop action."""
|
||||
if self._ads_var_stop:
|
||||
self._ads_hub.write_by_name(self._ads_var_stop, True, pyads.PLCTYPE_BOOL)
|
||||
|
||||
@override
|
||||
def set_cover_position(self, **kwargs: Any) -> None:
|
||||
"""Set cover position."""
|
||||
position = kwargs[ATTR_POSITION]
|
||||
@@ -164,7 +159,6 @@ class AdsCover(AdsEntity, CoverEntity):
|
||||
self._ads_var_pos_set, position, pyads.PLCTYPE_BYTE
|
||||
)
|
||||
|
||||
@override
|
||||
def open_cover(self, **kwargs: Any) -> None:
|
||||
"""Move the cover up."""
|
||||
if self._ads_var_open is not None:
|
||||
@@ -172,7 +166,6 @@ class AdsCover(AdsEntity, CoverEntity):
|
||||
elif self._ads_var_pos_set is not None:
|
||||
self.set_cover_position(position=100)
|
||||
|
||||
@override
|
||||
def close_cover(self, **kwargs: Any) -> None:
|
||||
"""Move the cover down."""
|
||||
if self._ads_var_close is not None:
|
||||
@@ -180,7 +173,6 @@ class AdsCover(AdsEntity, CoverEntity):
|
||||
elif self._ads_var_pos_set is not None:
|
||||
self.set_cover_position(position=0)
|
||||
|
||||
@override
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
"""Return False if state has not been updated yet."""
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import asyncio
|
||||
from asyncio import timeout
|
||||
import logging
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.helpers.entity import Entity
|
||||
|
||||
@@ -64,7 +64,6 @@ class AdsEntity(Entity):
|
||||
except TimeoutError:
|
||||
_LOGGER.debug("Variable %s: Timeout during first update", ads_var)
|
||||
|
||||
@override
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
"""Return False if state has not been updated yet."""
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Support for ADS light sources."""
|
||||
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
import pyads
|
||||
import voluptuous as vol
|
||||
@@ -120,7 +120,6 @@ class AdsLight(AdsEntity, LightEntity):
|
||||
else DEFAULT_MAX_KELVIN
|
||||
)
|
||||
|
||||
@override
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Register device notification."""
|
||||
await self.async_initialize_device(self._ads_var, pyads.PLCTYPE_BOOL)
|
||||
@@ -139,25 +138,21 @@ class AdsLight(AdsEntity, LightEntity):
|
||||
STATE_KEY_COLOR_TEMP_KELVIN,
|
||||
)
|
||||
|
||||
@override
|
||||
@property
|
||||
def brightness(self) -> int | None:
|
||||
"""Return the brightness of the light (0..255)."""
|
||||
return self._state_dict[STATE_KEY_BRIGHTNESS]
|
||||
|
||||
@override
|
||||
@property
|
||||
def color_temp_kelvin(self) -> int | None:
|
||||
"""Return the color temperature in Kelvin."""
|
||||
return self._state_dict[STATE_KEY_COLOR_TEMP_KELVIN]
|
||||
|
||||
@override
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return True if the entity is on."""
|
||||
return self._state_dict[STATE_KEY_STATE]
|
||||
|
||||
@override
|
||||
def turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn the light on or set a specific dimmer value."""
|
||||
brightness = kwargs.get(ATTR_BRIGHTNESS)
|
||||
@@ -175,7 +170,6 @@ class AdsLight(AdsEntity, LightEntity):
|
||||
self._ads_var_color_temp_kelvin, color_temp, pyads.PLCTYPE_UINT
|
||||
)
|
||||
|
||||
@override
|
||||
def turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn the light off."""
|
||||
self._ads_hub.write_by_name(self._ads_var, False, pyads.PLCTYPE_BOOL)
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
"""Support for ADS select entities."""
|
||||
|
||||
from typing import override
|
||||
|
||||
import pyads
|
||||
import voluptuous as vol
|
||||
|
||||
@@ -66,7 +64,6 @@ class AdsSelect(AdsEntity, SelectEntity):
|
||||
self._attr_options = options
|
||||
self._attr_current_option = None
|
||||
|
||||
@override
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Register device notification."""
|
||||
await self.async_initialize_device(self._ads_var, pyads.PLCTYPE_INT)
|
||||
@@ -74,7 +71,6 @@ class AdsSelect(AdsEntity, SelectEntity):
|
||||
self._ads_var, pyads.PLCTYPE_INT, self._handle_ads_value
|
||||
)
|
||||
|
||||
@override
|
||||
def select_option(self, option: str) -> None:
|
||||
"""Change the selected option."""
|
||||
if option in self._attr_options:
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
"""Support for ADS sensors."""
|
||||
|
||||
from typing import override
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.sensor import (
|
||||
@@ -110,7 +108,6 @@ class AdsSensor(AdsEntity, SensorEntity):
|
||||
self._attr_state_class = state_class
|
||||
self._attr_native_unit_of_measurement = unit_of_measurement
|
||||
|
||||
@override
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Register device notification."""
|
||||
await self.async_initialize_device(
|
||||
@@ -120,7 +117,6 @@ class AdsSensor(AdsEntity, SensorEntity):
|
||||
self._factor,
|
||||
)
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_value(self) -> StateType:
|
||||
"""Return the state of the device."""
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Support for ADS switch platform."""
|
||||
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
import pyads
|
||||
import voluptuous as vol
|
||||
@@ -46,23 +46,19 @@ def setup_platform(
|
||||
class AdsSwitch(AdsEntity, SwitchEntity):
|
||||
"""Representation of an ADS switch device."""
|
||||
|
||||
@override
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Register device notification."""
|
||||
await self.async_initialize_device(self._ads_var, pyads.PLCTYPE_BOOL)
|
||||
|
||||
@override
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return True if the entity is on."""
|
||||
return self._state_dict[STATE_KEY_STATE]
|
||||
|
||||
@override
|
||||
def turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn the switch on."""
|
||||
self._ads_hub.write_by_name(self._ads_var, True, pyads.PLCTYPE_BOOL)
|
||||
|
||||
@override
|
||||
def turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn the switch off."""
|
||||
self._ads_hub.write_by_name(self._ads_var, False, pyads.PLCTYPE_BOOL)
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
"""Support for ADS valves."""
|
||||
|
||||
from typing import override
|
||||
|
||||
import pyads
|
||||
import voluptuous as vol
|
||||
|
||||
@@ -69,18 +67,15 @@ class AdsValve(AdsEntity, ValveEntity):
|
||||
self._attr_reports_position = False
|
||||
self._attr_is_closed = True
|
||||
|
||||
@override
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Register device notification."""
|
||||
await self.async_initialize_device(self._ads_var, pyads.PLCTYPE_BOOL)
|
||||
|
||||
@override
|
||||
def open_valve(self, **kwargs) -> None:
|
||||
"""Open the valve."""
|
||||
self._ads_hub.write_by_name(self._ads_var, True, pyads.PLCTYPE_BOOL)
|
||||
self._attr_is_closed = False
|
||||
|
||||
@override
|
||||
def close_valve(self, **kwargs) -> None:
|
||||
"""Close the valve."""
|
||||
self._ads_hub.write_by_name(self._ads_var, False, pyads.PLCTYPE_BOOL)
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
"""Binary Sensor platform for Advantage Air integration."""
|
||||
|
||||
from typing import override
|
||||
|
||||
from homeassistant.components.binary_sensor import (
|
||||
BinarySensorDeviceClass,
|
||||
BinarySensorEntity,
|
||||
@@ -56,7 +54,6 @@ class AdvantageAirFilter(AdvantageAirAcEntity, BinarySensorEntity):
|
||||
super().__init__(coordinator, ac_key)
|
||||
self._attr_unique_id += "-filter"
|
||||
|
||||
@override
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return if filter needs cleaning."""
|
||||
@@ -76,7 +73,6 @@ class AdvantageAirZoneMotion(AdvantageAirZoneEntity, BinarySensorEntity):
|
||||
self._attr_name = f"{self._zone['name']} motion"
|
||||
self._attr_unique_id += "-motion"
|
||||
|
||||
@override
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return if motion is detect."""
|
||||
@@ -97,7 +93,6 @@ class AdvantageAirZoneMyZone(AdvantageAirZoneEntity, BinarySensorEntity):
|
||||
self._attr_name = f"{self._zone['name']} myZone"
|
||||
self._attr_unique_id += "-myzone"
|
||||
|
||||
@override
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return if this zone is the myZone."""
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from decimal import Decimal
|
||||
import logging
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.components.climate import (
|
||||
ATTR_TARGET_TEMP_HIGH,
|
||||
@@ -155,14 +155,12 @@ class AdvantageAirAC(AdvantageAirAcEntity, ClimateEntity):
|
||||
SUPPORTED_FEATURES_MYZONE | self._support_preset
|
||||
)
|
||||
|
||||
@override
|
||||
@callback
|
||||
def _handle_coordinator_update(self) -> None:
|
||||
"""Handle updated data from the coordinator."""
|
||||
self._async_configure_preset()
|
||||
super()._handle_coordinator_update()
|
||||
|
||||
@override
|
||||
@property
|
||||
def current_temperature(self) -> float | None:
|
||||
"""Return the selected zones current temperature."""
|
||||
@@ -170,7 +168,6 @@ class AdvantageAirAC(AdvantageAirAcEntity, ClimateEntity):
|
||||
return self._myzone["measuredTemp"]
|
||||
return None
|
||||
|
||||
@override
|
||||
@property
|
||||
def target_temperature(self) -> float | None:
|
||||
"""Return the current target temperature."""
|
||||
@@ -180,7 +177,6 @@ class AdvantageAirAC(AdvantageAirAcEntity, ClimateEntity):
|
||||
return self._myzone["setTemp"]
|
||||
return self._ac["setTemp"]
|
||||
|
||||
@override
|
||||
@property
|
||||
def hvac_mode(self) -> HVACMode | None:
|
||||
"""Return the current HVAC modes."""
|
||||
@@ -188,7 +184,6 @@ class AdvantageAirAC(AdvantageAirAcEntity, ClimateEntity):
|
||||
return ADVANTAGE_AIR_HVAC_MODES.get(self._ac["mode"])
|
||||
return HVACMode.OFF
|
||||
|
||||
@override
|
||||
@property
|
||||
def hvac_action(self) -> HVACAction | None:
|
||||
"""Return the current running HVAC action."""
|
||||
@@ -200,30 +195,25 @@ class AdvantageAirAC(AdvantageAirAcEntity, ClimateEntity):
|
||||
)
|
||||
return HVAC_ACTIONS.get(self._ac["mode"])
|
||||
|
||||
@override
|
||||
@property
|
||||
def fan_mode(self) -> str | None:
|
||||
"""Return the current fan modes."""
|
||||
return FAN_AUTO if self._ac["fan"] == ADVANTAGE_AIR_MYFAN else self._ac["fan"]
|
||||
|
||||
@override
|
||||
@property
|
||||
def target_temperature_high(self) -> float | None:
|
||||
"""Return the temperature cool mode is enabled."""
|
||||
return self._ac.get(ADVANTAGE_AIR_COOL_TARGET)
|
||||
|
||||
@override
|
||||
@property
|
||||
def target_temperature_low(self) -> float | None:
|
||||
"""Return the temperature heat mode is enabled."""
|
||||
return self._ac.get(ADVANTAGE_AIR_HEAT_TARGET)
|
||||
|
||||
@override
|
||||
async def async_turn_on(self) -> None:
|
||||
"""Set the HVAC State to on."""
|
||||
await self.async_update_ac({"state": ADVANTAGE_AIR_STATE_ON})
|
||||
|
||||
@override
|
||||
async def async_turn_off(self) -> None:
|
||||
"""Set the HVAC State to off."""
|
||||
await self.async_update_ac(
|
||||
@@ -232,7 +222,6 @@ class AdvantageAirAC(AdvantageAirAcEntity, ClimateEntity):
|
||||
}
|
||||
)
|
||||
|
||||
@override
|
||||
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
|
||||
"""Set the HVAC Mode and State."""
|
||||
if hvac_mode == HVACMode.OFF:
|
||||
@@ -247,7 +236,6 @@ class AdvantageAirAC(AdvantageAirAcEntity, ClimateEntity):
|
||||
}
|
||||
)
|
||||
|
||||
@override
|
||||
async def async_set_fan_mode(self, fan_mode: str) -> None:
|
||||
"""Set the Fan Mode."""
|
||||
if fan_mode == FAN_AUTO and self._ac.get(ADVANTAGE_AIR_AUTOFAN_ENABLED):
|
||||
@@ -256,7 +244,6 @@ class AdvantageAirAC(AdvantageAirAcEntity, ClimateEntity):
|
||||
mode = fan_mode
|
||||
await self.async_update_ac({"fan": mode})
|
||||
|
||||
@override
|
||||
async def async_set_temperature(self, **kwargs: Any) -> None:
|
||||
"""Set the Temperature."""
|
||||
if ATTR_TEMPERATURE in kwargs:
|
||||
@@ -269,7 +256,6 @@ class AdvantageAirAC(AdvantageAirAcEntity, ClimateEntity):
|
||||
}
|
||||
)
|
||||
|
||||
@override
|
||||
async def async_set_preset_mode(self, preset_mode: str) -> None:
|
||||
"""Set the preset mode."""
|
||||
change = {}
|
||||
@@ -302,7 +288,6 @@ class AdvantageAirZone(AdvantageAirZoneEntity, ClimateEntity):
|
||||
super().__init__(coordinator, ac_key, zone_key)
|
||||
self._attr_name = self._zone["name"]
|
||||
|
||||
@override
|
||||
@property
|
||||
def hvac_mode(self) -> HVACMode:
|
||||
"""Return the current state as HVAC mode."""
|
||||
@@ -310,7 +295,6 @@ class AdvantageAirZone(AdvantageAirZoneEntity, ClimateEntity):
|
||||
return HVACMode.HEAT_COOL
|
||||
return HVACMode.OFF
|
||||
|
||||
@override
|
||||
@property
|
||||
def hvac_action(self) -> HVACAction | None:
|
||||
"""Return the HVAC action.
|
||||
@@ -331,29 +315,24 @@ class AdvantageAirZone(AdvantageAirZoneEntity, ClimateEntity):
|
||||
return master_action
|
||||
return HVACAction.OFF
|
||||
|
||||
@override
|
||||
@property
|
||||
def current_temperature(self) -> float | None:
|
||||
"""Return the current temperature."""
|
||||
return self._zone["measuredTemp"]
|
||||
|
||||
@override
|
||||
@property
|
||||
def target_temperature(self) -> float:
|
||||
"""Return the target temperature."""
|
||||
return self._zone["setTemp"]
|
||||
|
||||
@override
|
||||
async def async_turn_on(self) -> None:
|
||||
"""Set the HVAC State to on."""
|
||||
await self.async_update_zone({"state": ADVANTAGE_AIR_STATE_OPEN})
|
||||
|
||||
@override
|
||||
async def async_turn_off(self) -> None:
|
||||
"""Set the HVAC State to off."""
|
||||
await self.async_update_zone({"state": ADVANTAGE_AIR_STATE_CLOSE})
|
||||
|
||||
@override
|
||||
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
|
||||
"""Set the HVAC Mode and State."""
|
||||
if hvac_mode == HVACMode.OFF:
|
||||
@@ -361,7 +340,6 @@ class AdvantageAirZone(AdvantageAirZoneEntity, ClimateEntity):
|
||||
else:
|
||||
await self.async_turn_on()
|
||||
|
||||
@override
|
||||
async def async_set_temperature(self, **kwargs: Any) -> None:
|
||||
"""Set the Temperature."""
|
||||
temp = kwargs.get(ATTR_TEMPERATURE)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Config Flow for Advantage Air integration."""
|
||||
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from advantage_air import ApiError, advantage_air
|
||||
import voluptuous as vol
|
||||
@@ -28,7 +28,6 @@ class AdvantageAirConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
|
||||
DOMAIN = DOMAIN
|
||||
|
||||
@override
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from advantage_air import ApiError, advantage_air
|
||||
|
||||
@@ -45,7 +45,6 @@ class AdvantageAirCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
||||
)
|
||||
self.api = api
|
||||
|
||||
@override
|
||||
async def _async_update_data(self) -> dict[str, Any]:
|
||||
"""Fetch data from the API."""
|
||||
try:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Cover platform for Advantage Air integration."""
|
||||
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.components.cover import (
|
||||
ATTR_POSITION,
|
||||
@@ -65,13 +65,11 @@ class AdvantageAirZoneVent(AdvantageAirZoneEntity, CoverEntity):
|
||||
super().__init__(coordinator, ac_key, zone_key)
|
||||
self._attr_name = self._zone["name"]
|
||||
|
||||
@override
|
||||
@property
|
||||
def is_closed(self) -> bool:
|
||||
"""Return if vent is fully closed."""
|
||||
return self._zone["state"] == ADVANTAGE_AIR_STATE_CLOSE
|
||||
|
||||
@override
|
||||
@property
|
||||
def current_cover_position(self) -> int:
|
||||
"""Return vents current position as a percentage."""
|
||||
@@ -79,19 +77,16 @@ class AdvantageAirZoneVent(AdvantageAirZoneEntity, CoverEntity):
|
||||
return self._zone["value"]
|
||||
return 0
|
||||
|
||||
@override
|
||||
async def async_open_cover(self, **kwargs: Any) -> None:
|
||||
"""Fully open zone vent."""
|
||||
await self.async_update_zone(
|
||||
{"state": ADVANTAGE_AIR_STATE_OPEN, "value": 100},
|
||||
)
|
||||
|
||||
@override
|
||||
async def async_close_cover(self, **kwargs: Any) -> None:
|
||||
"""Fully close zone vent."""
|
||||
await self.async_update_zone({"state": ADVANTAGE_AIR_STATE_CLOSE})
|
||||
|
||||
@override
|
||||
async def async_set_cover_position(self, **kwargs: Any) -> None:
|
||||
"""Change vent position."""
|
||||
position = round(kwargs[ATTR_POSITION] / 5) * 5
|
||||
@@ -121,18 +116,15 @@ class AdvantageAirThingCover(AdvantageAirThingEntity, CoverEntity):
|
||||
super().__init__(coordinator, thing)
|
||||
self._attr_device_class = device_class
|
||||
|
||||
@override
|
||||
@property
|
||||
def is_closed(self) -> bool:
|
||||
"""Return if cover is fully closed."""
|
||||
return self._data["value"] == 0
|
||||
|
||||
@override
|
||||
async def async_open_cover(self, **kwargs: Any) -> None:
|
||||
"""Fully open zone vent."""
|
||||
return await self.async_turn_on()
|
||||
|
||||
@override
|
||||
async def async_close_cover(self, **kwargs: Any) -> None:
|
||||
"""Fully close zone vent."""
|
||||
return await self.async_turn_off()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Light platform for Advantage Air integration."""
|
||||
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.components.light import ATTR_BRIGHTNESS, ColorMode, LightEntity
|
||||
from homeassistant.core import HomeAssistant
|
||||
@@ -69,18 +69,15 @@ class AdvantageAirLight(AdvantageAirEntity, LightEntity):
|
||||
"""Return the light object."""
|
||||
return self.coordinator.data["myLights"]["lights"][self._id]
|
||||
|
||||
@override
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return if the light is on."""
|
||||
return self._data["state"] == ADVANTAGE_AIR_STATE_ON
|
||||
|
||||
@override
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn the light on."""
|
||||
await self.async_update_state(True)
|
||||
|
||||
@override
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn the light off."""
|
||||
await self.async_update_state(False)
|
||||
@@ -101,13 +98,11 @@ class AdvantageAirLightDimmable(AdvantageAirLight):
|
||||
coordinator.api.lights.async_update_value, self._id
|
||||
)
|
||||
|
||||
@override
|
||||
@property
|
||||
def brightness(self) -> int:
|
||||
"""Return the brightness of this light between 0..255."""
|
||||
return round(self._data["value"] * 255 / 100)
|
||||
|
||||
@override
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn the light on and optionally set the brightness."""
|
||||
if ATTR_BRIGHTNESS in kwargs:
|
||||
@@ -128,13 +123,11 @@ class AdvantageAirThingLightDimmable(AdvantageAirThingEntity, LightEntity):
|
||||
_attr_color_mode = ColorMode.BRIGHTNESS
|
||||
_attr_supported_color_modes = {ColorMode.BRIGHTNESS}
|
||||
|
||||
@override
|
||||
@property
|
||||
def brightness(self) -> int:
|
||||
"""Return the brightness of this light between 0..255."""
|
||||
return round(self._data["value"] * 255 / 100)
|
||||
|
||||
@override
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn the light on by setting the brightness."""
|
||||
await self.async_update_value(round(kwargs.get(ATTR_BRIGHTNESS, 255) / 2.55))
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
"""Select platform for Advantage Air integration."""
|
||||
|
||||
from typing import override
|
||||
|
||||
from homeassistant.components.select import SelectEntity
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||
@@ -49,13 +47,11 @@ class AdvantageAirMyZone(AdvantageAirAcEntity, SelectEntity):
|
||||
self._number_to_name[zone["number"]] = zone["name"]
|
||||
self._attr_options.append(zone["name"])
|
||||
|
||||
@override
|
||||
@property
|
||||
def current_option(self) -> str:
|
||||
"""Return the current MyZone."""
|
||||
return self._number_to_name[self._ac["myZone"]]
|
||||
|
||||
@override
|
||||
async def async_select_option(self, option: str) -> None:
|
||||
"""Set the MyZone."""
|
||||
await self.async_update_ac({"myZone": self._name_to_number[option]})
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Sensor platform for Advantage Air integration."""
|
||||
|
||||
from decimal import Decimal
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.components.sensor import (
|
||||
SensorDeviceClass,
|
||||
@@ -66,13 +66,11 @@ class AdvantageAirTimeTo(AdvantageAirAcEntity, SensorEntity):
|
||||
self._attr_name = f"Time to {action}"
|
||||
self._attr_unique_id += f"-timeto{action}"
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_value(self) -> Decimal:
|
||||
"""Return the current value."""
|
||||
return self._ac[self._time_key]
|
||||
|
||||
@override
|
||||
@property
|
||||
def icon(self) -> str:
|
||||
"""Return a representative icon of the timer."""
|
||||
@@ -101,7 +99,6 @@ class AdvantageAirZoneVent(AdvantageAirZoneEntity, SensorEntity):
|
||||
self._attr_name = f"{self._zone['name']} vent"
|
||||
self._attr_unique_id += "-vent"
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_value(self) -> Decimal:
|
||||
"""Return the current value of the air vent."""
|
||||
@@ -109,7 +106,6 @@ class AdvantageAirZoneVent(AdvantageAirZoneEntity, SensorEntity):
|
||||
return self._zone["value"]
|
||||
return Decimal(0)
|
||||
|
||||
@override
|
||||
@property
|
||||
def icon(self) -> str:
|
||||
"""Return a representative icon."""
|
||||
@@ -133,13 +129,11 @@ class AdvantageAirZoneSignal(AdvantageAirZoneEntity, SensorEntity):
|
||||
self._attr_name = f"{self._zone['name']} signal"
|
||||
self._attr_unique_id += "-signal"
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_value(self) -> Decimal:
|
||||
"""Return the current value of the wireless signal."""
|
||||
return self._zone["rssi"]
|
||||
|
||||
@override
|
||||
@property
|
||||
def icon(self) -> str:
|
||||
"""Return a representative icon."""
|
||||
@@ -171,7 +165,6 @@ class AdvantageAirZoneTemp(AdvantageAirZoneEntity, SensorEntity):
|
||||
self._attr_name = f"{self._zone['name']} temperature"
|
||||
self._attr_unique_id += "-temp"
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_value(self) -> Decimal:
|
||||
"""Return the current value of the measured temperature."""
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Switch platform for Advantage Air integration."""
|
||||
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.components.switch import SwitchDeviceClass, SwitchEntity
|
||||
from homeassistant.core import HomeAssistant
|
||||
@@ -56,18 +56,15 @@ class AdvantageAirFreshAir(AdvantageAirAcEntity, SwitchEntity):
|
||||
super().__init__(coordinator, ac_key)
|
||||
self._attr_unique_id += "-freshair"
|
||||
|
||||
@override
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return the fresh air status."""
|
||||
return self._ac["freshAirStatus"] == ADVANTAGE_AIR_STATE_ON
|
||||
|
||||
@override
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn fresh air on."""
|
||||
await self.async_update_ac({"freshAirStatus": ADVANTAGE_AIR_STATE_ON})
|
||||
|
||||
@override
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn fresh air off."""
|
||||
await self.async_update_ac({"freshAirStatus": ADVANTAGE_AIR_STATE_OFF})
|
||||
@@ -85,18 +82,15 @@ class AdvantageAirMyFan(AdvantageAirAcEntity, SwitchEntity):
|
||||
super().__init__(coordinator, ac_key)
|
||||
self._attr_unique_id += "-myfan"
|
||||
|
||||
@override
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return the MyFan status."""
|
||||
return self._ac[ADVANTAGE_AIR_AUTOFAN_ENABLED]
|
||||
|
||||
@override
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn MyFan on."""
|
||||
await self.async_update_ac({ADVANTAGE_AIR_AUTOFAN_ENABLED: True})
|
||||
|
||||
@override
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn MyFan off."""
|
||||
await self.async_update_ac({ADVANTAGE_AIR_AUTOFAN_ENABLED: False})
|
||||
@@ -114,18 +108,15 @@ class AdvantageAirNightMode(AdvantageAirAcEntity, SwitchEntity):
|
||||
super().__init__(coordinator, ac_key)
|
||||
self._attr_unique_id += "-nightmode"
|
||||
|
||||
@override
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return the Night Mode status."""
|
||||
return self._ac[ADVANTAGE_AIR_NIGHT_MODE_ENABLED]
|
||||
|
||||
@override
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn Night Mode on."""
|
||||
await self.async_update_ac({ADVANTAGE_AIR_NIGHT_MODE_ENABLED: True})
|
||||
|
||||
@override
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn Night Mode off."""
|
||||
await self.async_update_ac({ADVANTAGE_AIR_NIGHT_MODE_ENABLED: False})
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
"""Advantage Air Update platform."""
|
||||
|
||||
from typing import override
|
||||
|
||||
from homeassistant.components.update import UpdateEntity
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers.device_registry import DeviceInfo
|
||||
@@ -41,13 +39,11 @@ class AdvantageAirApp(AdvantageAirEntity, UpdateEntity):
|
||||
sw_version=self.coordinator.data["system"]["myAppRev"],
|
||||
)
|
||||
|
||||
@override
|
||||
@property
|
||||
def installed_version(self) -> str:
|
||||
"""Return the current app version."""
|
||||
return self.coordinator.data["system"]["myAppRev"]
|
||||
|
||||
@override
|
||||
@property
|
||||
def latest_version(self) -> str:
|
||||
"""Return if there is an update."""
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Config flow for AEMET OpenData."""
|
||||
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from aemet_opendata.exceptions import AuthError
|
||||
from aemet_opendata.interface import AEMET, ConnectionOptions
|
||||
@@ -31,7 +31,6 @@ OPTIONS_FLOW = {
|
||||
class AemetConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
"""Config flow for AEMET OpenData."""
|
||||
|
||||
@override
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
@@ -81,7 +80,6 @@ class AemetConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
},
|
||||
)
|
||||
|
||||
@override
|
||||
@staticmethod
|
||||
@callback
|
||||
def async_get_options_flow(
|
||||
|
||||
@@ -4,7 +4,7 @@ from asyncio import timeout
|
||||
from dataclasses import dataclass
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
from typing import Any, Final, cast, override
|
||||
from typing import Any, Final, cast
|
||||
|
||||
from aemet_opendata.const import (
|
||||
AOD_CONDITION,
|
||||
@@ -60,7 +60,6 @@ class WeatherUpdateCoordinator(DataUpdateCoordinator):
|
||||
update_interval=WEATHER_UPDATE_INTERVAL,
|
||||
)
|
||||
|
||||
@override
|
||||
async def _async_update_data(self) -> dict[str, Any]:
|
||||
"""Update coordinator data."""
|
||||
async with timeout(API_TIMEOUT):
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Support for the AEMET OpenData images."""
|
||||
|
||||
from typing import Final, override
|
||||
from typing import Final
|
||||
|
||||
from aemet_opendata.const import AOD_DATETIME, AOD_IMG_BYTES, AOD_IMG_TYPE, AOD_RADAR
|
||||
from aemet_opendata.helpers import dict_nested_value
|
||||
@@ -67,7 +67,6 @@ class AemetImage(AemetEntity, ImageEntity):
|
||||
|
||||
self._async_update_attrs()
|
||||
|
||||
@override
|
||||
@callback
|
||||
def _handle_coordinator_update(self) -> None:
|
||||
"""Update attributes when the coordinator updates."""
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
from typing import Final, override
|
||||
from typing import Final
|
||||
|
||||
from aemet_opendata.const import (
|
||||
AOD_CONDITION,
|
||||
@@ -398,7 +398,6 @@ class AemetSensor(AemetEntity, SensorEntity):
|
||||
self.entity_description = description
|
||||
self._attr_unique_id = f"{unique_id}-{description.key}"
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_value(self):
|
||||
"""Return the state of the device."""
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
"""Support for the AEMET OpenData service."""
|
||||
|
||||
from typing import override
|
||||
|
||||
from aemet_opendata.const import (
|
||||
AOD_CONDITION,
|
||||
AOD_FORECAST_DAILY,
|
||||
@@ -75,56 +73,47 @@ class AemetWeather(
|
||||
super().__init__(coordinator, name, unique_id)
|
||||
self._attr_unique_id = unique_id
|
||||
|
||||
@override
|
||||
@property
|
||||
def condition(self) -> str | None:
|
||||
"""Return the current condition."""
|
||||
cond = self.get_aemet_value([AOD_WEATHER, AOD_CONDITION])
|
||||
return CONDITIONS_MAP.get(cond)
|
||||
|
||||
@override
|
||||
@callback
|
||||
def _async_forecast_daily(self) -> list[Forecast]:
|
||||
"""Return the daily forecast in native units."""
|
||||
return self.get_aemet_forecast(AOD_FORECAST_DAILY)
|
||||
|
||||
@override
|
||||
@callback
|
||||
def _async_forecast_hourly(self) -> list[Forecast]:
|
||||
"""Return the hourly forecast in native units."""
|
||||
return self.get_aemet_forecast(AOD_FORECAST_HOURLY)
|
||||
|
||||
@override
|
||||
@property
|
||||
def humidity(self) -> float | None:
|
||||
"""Return the humidity."""
|
||||
return self.get_aemet_value([AOD_WEATHER, AOD_HUMIDITY])
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_pressure(self) -> float | None:
|
||||
"""Return the pressure."""
|
||||
return self.get_aemet_value([AOD_WEATHER, AOD_PRESSURE])
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_temperature(self) -> float | None:
|
||||
"""Return the temperature."""
|
||||
return self.get_aemet_value([AOD_WEATHER, AOD_TEMP])
|
||||
|
||||
@override
|
||||
@property
|
||||
def wind_bearing(self) -> float | None:
|
||||
"""Return the wind bearing."""
|
||||
return self.get_aemet_value([AOD_WEATHER, AOD_WIND_DIRECTION])
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_wind_gust_speed(self) -> float | None:
|
||||
"""Return the wind gust speed in native units."""
|
||||
return self.get_aemet_value([AOD_WEATHER, AOD_WIND_SPEED_MAX])
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_wind_speed(self) -> float | None:
|
||||
"""Return the wind speed."""
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Config flow for AfterShip integration."""
|
||||
|
||||
import logging
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from pyaftership import AfterShip, AfterShipException
|
||||
import voluptuous as vol
|
||||
@@ -20,7 +20,6 @@ class AfterShipConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
|
||||
VERSION = 1
|
||||
|
||||
@override
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Support for non-delivered packages recorded in AfterShip."""
|
||||
|
||||
import logging
|
||||
from typing import Any, Final, override
|
||||
from typing import Any, Final
|
||||
|
||||
from pyaftership import AfterShip, AfterShipException
|
||||
|
||||
@@ -95,19 +95,16 @@ class AfterShipSensor(SensorEntity):
|
||||
self.aftership = aftership
|
||||
self._attr_name = name
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_value(self) -> int | None:
|
||||
"""Return the state of the sensor."""
|
||||
return self._state
|
||||
|
||||
@override
|
||||
@property
|
||||
def extra_state_attributes(self) -> dict[str, str]:
|
||||
"""Return attributes for the sensor."""
|
||||
return self._attributes
|
||||
|
||||
@override
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Register callbacks."""
|
||||
self.async_on_remove(
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
"""Support for Agent DVR Alarm Control Panels."""
|
||||
|
||||
from typing import override
|
||||
|
||||
from homeassistant.components.alarm_control_panel import (
|
||||
AlarmControlPanelEntity,
|
||||
AlarmControlPanelEntityFeature,
|
||||
@@ -72,27 +70,23 @@ class AgentBaseStation(AlarmControlPanelEntity):
|
||||
else:
|
||||
self._attr_alarm_state = AlarmControlPanelState.DISARMED
|
||||
|
||||
@override
|
||||
async def async_alarm_disarm(self, code: str | None = None) -> None:
|
||||
"""Send disarm command."""
|
||||
await self._client.disarm()
|
||||
self._attr_alarm_state = AlarmControlPanelState.DISARMED
|
||||
|
||||
@override
|
||||
async def async_alarm_arm_away(self, code: str | None = None) -> None:
|
||||
"""Send arm away command. Uses custom mode."""
|
||||
await self._client.arm()
|
||||
await self._client.set_active_profile(CONF_AWAY_MODE_NAME)
|
||||
self._attr_alarm_state = AlarmControlPanelState.ARMED_AWAY
|
||||
|
||||
@override
|
||||
async def async_alarm_arm_home(self, code: str | None = None) -> None:
|
||||
"""Send arm home command. Uses custom mode."""
|
||||
await self._client.arm()
|
||||
await self._client.set_active_profile(CONF_HOME_MODE_NAME)
|
||||
self._attr_alarm_state = AlarmControlPanelState.ARMED_HOME
|
||||
|
||||
@override
|
||||
async def async_alarm_arm_night(self, code: str | None = None) -> None:
|
||||
"""Send arm night command. Uses custom mode."""
|
||||
await self._client.arm()
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
from typing import override
|
||||
|
||||
from agent import AgentError
|
||||
|
||||
@@ -95,7 +94,6 @@ class AgentCamera(MjpegCamera):
|
||||
"alerts_enabled": self.device.alerts_active,
|
||||
}
|
||||
|
||||
@override
|
||||
@property
|
||||
def is_recording(self) -> bool:
|
||||
"""Return whether the monitor is recording."""
|
||||
@@ -116,13 +114,11 @@ class AgentCamera(MjpegCamera):
|
||||
"""Return True if entity is connected."""
|
||||
return self.device.connected
|
||||
|
||||
@override
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return true if on."""
|
||||
return self.device.online
|
||||
|
||||
@override
|
||||
@property
|
||||
def motion_detection_enabled(self) -> bool:
|
||||
"""Return the camera motion detection status."""
|
||||
@@ -136,12 +132,10 @@ class AgentCamera(MjpegCamera):
|
||||
"""Disable alerts."""
|
||||
await self.device.alerts_off()
|
||||
|
||||
@override
|
||||
async def async_enable_motion_detection(self) -> None:
|
||||
"""Enable motion detection."""
|
||||
await self.device.detector_on()
|
||||
|
||||
@override
|
||||
async def async_disable_motion_detection(self) -> None:
|
||||
"""Disable motion detection."""
|
||||
await self.device.detector_off()
|
||||
@@ -154,7 +148,6 @@ class AgentCamera(MjpegCamera):
|
||||
"""Stop recording."""
|
||||
await self.device.record_stop()
|
||||
|
||||
@override
|
||||
async def async_turn_on(self) -> None:
|
||||
"""Enable the camera."""
|
||||
await self.device.enable()
|
||||
@@ -163,7 +156,6 @@ class AgentCamera(MjpegCamera):
|
||||
"""Take a snapshot."""
|
||||
await self.device.snapshot()
|
||||
|
||||
@override
|
||||
async def async_turn_off(self) -> None:
|
||||
"""Disable the camera."""
|
||||
await self.device.disable()
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Config flow to configure Agent devices."""
|
||||
|
||||
from contextlib import suppress
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from agent import AgentConnectionError, AgentError
|
||||
from agent.a import Agent
|
||||
@@ -20,7 +20,6 @@ DEFAULT_PORT = 8090
|
||||
class AgentFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
"""Handle an Agent config flow."""
|
||||
|
||||
@override
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from collections.abc import AsyncGenerator
|
||||
import contextlib
|
||||
from typing import final, override
|
||||
from typing import final
|
||||
|
||||
from propcache.api import cached_property
|
||||
|
||||
@@ -28,7 +28,6 @@ class AITaskEntity(RestoreEntity):
|
||||
_attr_supported_features = AITaskEntityFeature(0)
|
||||
__last_activity: str | None = None
|
||||
|
||||
@override
|
||||
@property
|
||||
@final
|
||||
def state(self) -> str | None:
|
||||
@@ -37,13 +36,11 @@ class AITaskEntity(RestoreEntity):
|
||||
return None
|
||||
return self.__last_activity
|
||||
|
||||
@override
|
||||
@cached_property
|
||||
def supported_features(self) -> AITaskEntityFeature:
|
||||
"""Flag supported features."""
|
||||
return self._attr_supported_features
|
||||
|
||||
@override
|
||||
async def async_internal_added_to_hass(self) -> None:
|
||||
"""Call when the entity is added to hass."""
|
||||
await super().async_internal_added_to_hass()
|
||||
|
||||
@@ -6,7 +6,7 @@ import io
|
||||
import mimetypes
|
||||
from pathlib import Path
|
||||
import tempfile
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
@@ -260,7 +260,6 @@ class GenDataTask:
|
||||
llm_api: llm.API | None = None
|
||||
"""API to provide to the LLM."""
|
||||
|
||||
@override
|
||||
def __str__(self) -> str:
|
||||
"""Return task as a string."""
|
||||
return f"<GenDataTask {self.name}: {id(self)}>"
|
||||
@@ -297,7 +296,6 @@ class GenImageTask:
|
||||
attachments: list[conversation.Attachment] | None = None
|
||||
"""List of attachments to go along the instructions."""
|
||||
|
||||
@override
|
||||
def __str__(self) -> str:
|
||||
"""Return task as a string."""
|
||||
return f"<GenImageTask {self.name}: {id(self)}>"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Config flow for Aidot integration."""
|
||||
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from aidot.client import AidotClient
|
||||
from aidot.const import CONF_ID, DEFAULT_COUNTRY_CODE, SUPPORTED_COUNTRY_CODES
|
||||
@@ -34,7 +34,6 @@ DATA_SCHEMA = vol.Schema(
|
||||
class AidotConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
"""Handle aidot config flow."""
|
||||
|
||||
@override
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
from typing import override
|
||||
|
||||
from aidot.client import AidotClient
|
||||
from aidot.const import (
|
||||
@@ -49,7 +48,6 @@ class AidotDeviceUpdateCoordinator(DataUpdateCoordinator[DeviceStatusData]):
|
||||
)
|
||||
self.device_client = device_client
|
||||
|
||||
@override
|
||||
async def _async_setup(self) -> None:
|
||||
"""Set up the coordinator."""
|
||||
self.device_client.on_status_update = self._handle_status_update
|
||||
@@ -58,7 +56,6 @@ class AidotDeviceUpdateCoordinator(DataUpdateCoordinator[DeviceStatusData]):
|
||||
"""Handle status callback."""
|
||||
self.async_set_updated_data(status)
|
||||
|
||||
@override
|
||||
async def _async_update_data(self) -> DeviceStatusData:
|
||||
"""Return current status."""
|
||||
return self.device_client.status
|
||||
@@ -89,7 +86,6 @@ class AidotDeviceManagerCoordinator(DataUpdateCoordinator[None]):
|
||||
self.client.set_token_fresh_cb(self.token_fresh_cb)
|
||||
self.device_coordinators: dict[str, AidotDeviceUpdateCoordinator] = {}
|
||||
|
||||
@override
|
||||
async def _async_setup(self) -> None:
|
||||
"""Set up the coordinator."""
|
||||
try:
|
||||
@@ -97,7 +93,6 @@ class AidotDeviceManagerCoordinator(DataUpdateCoordinator[None]):
|
||||
except AidotUserOrPassIncorrect as error:
|
||||
raise ConfigEntryError from error
|
||||
|
||||
@override
|
||||
async def _async_update_data(self) -> None:
|
||||
"""Update data async."""
|
||||
try:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Support for Aidot lights."""
|
||||
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.components.light import (
|
||||
ATTR_BRIGHTNESS,
|
||||
@@ -77,20 +77,17 @@ class AidotLight(CoordinatorEntity[AidotDeviceUpdateCoordinator], LightEntity):
|
||||
self._attr_color_temp_kelvin = self.coordinator.data.cct
|
||||
self._attr_rgbw_color = self.coordinator.data.rgbw
|
||||
|
||||
@override
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
"""Return if entity is available."""
|
||||
return super().available and self.coordinator.data.online
|
||||
|
||||
@override
|
||||
@callback
|
||||
def _handle_coordinator_update(self) -> None:
|
||||
"""Update."""
|
||||
self._update_status()
|
||||
super()._handle_coordinator_update()
|
||||
|
||||
@override
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn the light on, applying brightness, color temperature, RGBW, or plain on."""
|
||||
if ATTR_BRIGHTNESS in kwargs:
|
||||
@@ -117,7 +114,6 @@ class AidotLight(CoordinatorEntity[AidotDeviceUpdateCoordinator], LightEntity):
|
||||
self._attr_is_on = True
|
||||
self.async_write_ha_state()
|
||||
|
||||
@override
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn the light off."""
|
||||
await self.coordinator.device_client.async_turn_off()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
from typing import Final, final, override
|
||||
from typing import Final, final
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONCENTRATION_MICROGRAMS_PER_CUBIC_METER
|
||||
@@ -129,7 +129,6 @@ class AirQualityEntity(Entity):
|
||||
"""Return the NO2 (nitrogen dioxide) level."""
|
||||
return None
|
||||
|
||||
@override
|
||||
@final
|
||||
@property
|
||||
def state_attributes(self) -> dict[str, str | int | float]:
|
||||
@@ -142,13 +141,11 @@ class AirQualityEntity(Entity):
|
||||
|
||||
return data
|
||||
|
||||
@override
|
||||
@property
|
||||
def state(self) -> StateType:
|
||||
"""Return the current state."""
|
||||
return self.particulate_matter_2_5
|
||||
|
||||
@override
|
||||
@property
|
||||
def unit_of_measurement(self) -> str:
|
||||
"""Return the unit of measurement of this entity."""
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
from collections.abc import Awaitable, Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import override
|
||||
|
||||
from airgradient import AirGradientClient, ConfigurationControl
|
||||
|
||||
@@ -103,7 +102,6 @@ class AirGradientButton(AirGradientEntity, ButtonEntity):
|
||||
self.entity_description = description
|
||||
self._attr_unique_id = f"{coordinator.serial_number}-{description.key}"
|
||||
|
||||
@override
|
||||
@exception_handler
|
||||
async def async_press(self) -> None:
|
||||
"""Press the button."""
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Config flow for Airgradient."""
|
||||
|
||||
from collections.abc import Mapping
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from airgradient import (
|
||||
AirGradientClient,
|
||||
@@ -42,7 +42,6 @@ class AirGradientConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
if config.configuration_control is ConfigurationControl.NOT_INITIALIZED:
|
||||
await self.client.set_configuration_control(ConfigurationControl.LOCAL)
|
||||
|
||||
@override
|
||||
async def async_step_zeroconf(
|
||||
self, discovery_info: ZeroconfServiceInfo
|
||||
) -> ConfigFlowResult:
|
||||
@@ -84,7 +83,6 @@ class AirGradientConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
},
|
||||
)
|
||||
|
||||
@override
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
from dataclasses import dataclass
|
||||
from datetime import timedelta
|
||||
from typing import override
|
||||
|
||||
from airgradient import AirGradientClient, AirGradientError, Config, Measures
|
||||
|
||||
@@ -48,7 +47,6 @@ class AirGradientCoordinator(DataUpdateCoordinator[AirGradientData]):
|
||||
assert self.config_entry.unique_id
|
||||
self.serial_number = self.config_entry.unique_id
|
||||
|
||||
@override
|
||||
async def _async_setup(self) -> None:
|
||||
"""Set up the coordinator."""
|
||||
try:
|
||||
@@ -62,7 +60,6 @@ class AirGradientCoordinator(DataUpdateCoordinator[AirGradientData]):
|
||||
translation_placeholders={"error": str(error)},
|
||||
) from error
|
||||
|
||||
@override
|
||||
async def _async_update_data(self) -> AirGradientData:
|
||||
try:
|
||||
measures = await self.client.get_current_measures()
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
from collections.abc import Awaitable, Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import override
|
||||
|
||||
from airgradient import AirGradientClient, Config
|
||||
from airgradient.models import ConfigurationControl
|
||||
@@ -119,13 +118,11 @@ class AirGradientNumber(AirGradientEntity, NumberEntity):
|
||||
self.entity_description = description
|
||||
self._attr_unique_id = f"{coordinator.serial_number}-{description.key}"
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_value(self) -> int | None:
|
||||
"""Return the state of the number."""
|
||||
return self.entity_description.value_fn(self.coordinator.data.config)
|
||||
|
||||
@override
|
||||
@exception_handler
|
||||
async def async_set_native_value(self, value: float) -> None:
|
||||
"""Set the selected value."""
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
from collections.abc import Awaitable, Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import override
|
||||
|
||||
from airgradient import AirGradientClient, Config
|
||||
from airgradient.models import ConfigurationControl, LedBarMode, TemperatureUnit
|
||||
@@ -215,13 +214,11 @@ class AirGradientSelect(AirGradientEntity, SelectEntity):
|
||||
self.entity_description = description
|
||||
self._attr_unique_id = f"{coordinator.serial_number}-{description.key}"
|
||||
|
||||
@override
|
||||
@property
|
||||
def current_option(self) -> str | None:
|
||||
"""Return the state of the select."""
|
||||
return self.entity_description.value_fn(self.coordinator.data.config)
|
||||
|
||||
@override
|
||||
@exception_handler
|
||||
async def async_select_option(self, option: str) -> None:
|
||||
"""Change the selected option."""
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import override
|
||||
|
||||
from airgradient import Config
|
||||
from airgradient.models import (
|
||||
@@ -295,7 +294,6 @@ class AirGradientMeasurementSensor(AirGradientSensor):
|
||||
|
||||
entity_description: AirGradientMeasurementSensorEntityDescription
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_value(self) -> StateType:
|
||||
"""Return the state of the sensor."""
|
||||
@@ -319,7 +317,6 @@ class AirGradientConfigSensor(AirGradientSensor):
|
||||
is not ConfigurationControl.LOCAL
|
||||
)
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_value(self) -> StateType:
|
||||
"""Return the state of the sensor."""
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from collections.abc import Awaitable, Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from airgradient import AirGradientClient, Config
|
||||
from airgradient.models import ConfigurationControl
|
||||
@@ -96,20 +96,17 @@ class AirGradientSwitch(AirGradientEntity, SwitchEntity):
|
||||
self.entity_description = description
|
||||
self._attr_unique_id = f"{coordinator.serial_number}-{description.key}"
|
||||
|
||||
@override
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return the state of the switch."""
|
||||
return self.entity_description.value_fn(self.coordinator.data.config)
|
||||
|
||||
@override
|
||||
@exception_handler
|
||||
async def async_turn_on(self, **kwargs: Any) -> None:
|
||||
"""Turn the switch on."""
|
||||
await self.entity_description.set_value_fn(self.coordinator.client, True)
|
||||
await self.coordinator.async_request_refresh()
|
||||
|
||||
@override
|
||||
@exception_handler
|
||||
async def async_turn_off(self, **kwargs: Any) -> None:
|
||||
"""Turn the switch off."""
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
from typing import override
|
||||
|
||||
from airgradient import AirGradientConnectionError
|
||||
from propcache.api import cached_property
|
||||
@@ -42,25 +41,21 @@ class AirGradientUpdate(AirGradientEntity, UpdateEntity):
|
||||
super().__init__(coordinator)
|
||||
self._attr_unique_id = f"{coordinator.serial_number}-update"
|
||||
|
||||
@override
|
||||
@cached_property
|
||||
def should_poll(self) -> bool:
|
||||
"""Return True because we need to poll the latest version."""
|
||||
return True
|
||||
|
||||
@override
|
||||
@property
|
||||
def installed_version(self) -> str:
|
||||
"""Return the installed version of the entity."""
|
||||
return self.coordinator.data.measures.firmware_version
|
||||
|
||||
@override
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
"""Return if entity is available."""
|
||||
return super().available and self._attr_available
|
||||
|
||||
@override
|
||||
async def async_update(self) -> None:
|
||||
"""Update the entity."""
|
||||
try:
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from asyncio import timeout
|
||||
from http import HTTPStatus
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from aiohttp import ClientSession
|
||||
from airly import Airly
|
||||
@@ -26,7 +26,6 @@ class AirlyFlowHandler(ConfigFlow, domain=DOMAIN):
|
||||
|
||||
VERSION = 1
|
||||
|
||||
@override
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
|
||||
@@ -4,7 +4,6 @@ from asyncio import timeout
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
from math import ceil
|
||||
from typing import override
|
||||
|
||||
from aiohttp import ClientSession
|
||||
from aiohttp.client_exceptions import ClientConnectorError
|
||||
@@ -91,7 +90,6 @@ class AirlyDataUpdateCoordinator(DataUpdateCoordinator[dict[str, str | float | i
|
||||
update_interval=update_interval,
|
||||
)
|
||||
|
||||
@override
|
||||
async def _async_update_data(self) -> dict[str, str | float | int]:
|
||||
"""Update data via library."""
|
||||
data: dict[str, str | float | int] = {}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.components.sensor import (
|
||||
SensorDeviceClass,
|
||||
@@ -223,7 +223,6 @@ class AirlySensor(CoordinatorEntity[AirlyDataUpdateCoordinator], SensorEntity):
|
||||
self._attr_extra_state_attributes = description.attrs(coordinator.data)
|
||||
self.entity_description = description
|
||||
|
||||
@override
|
||||
@callback
|
||||
def _handle_coordinator_update(self) -> None:
|
||||
"""Handle updated data from the coordinator."""
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
"""Config flow for AirNow integration."""
|
||||
|
||||
import logging
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from pyairnow import WebServiceAPI
|
||||
from pyairnow.errors import AirNowError, EmptyResponseError, InvalidKeyError
|
||||
@@ -63,7 +63,6 @@ class AirNowConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
|
||||
VERSION = 2
|
||||
|
||||
@override
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
@@ -121,7 +120,6 @@ class AirNowConfigFlow(ConfigFlow, domain=DOMAIN):
|
||||
errors=errors,
|
||||
)
|
||||
|
||||
@override
|
||||
@staticmethod
|
||||
@callback
|
||||
def async_get_options_flow(
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from aiohttp import ClientSession
|
||||
from aiohttp.client_exceptions import ClientConnectorError
|
||||
@@ -69,7 +69,6 @@ class AirNowDataUpdateCoordinator(DataUpdateCoordinator[dict[str, Any]]):
|
||||
update_interval=update_interval,
|
||||
)
|
||||
|
||||
@override
|
||||
async def _async_update_data(self) -> dict[str, Any]:
|
||||
"""Update data via library."""
|
||||
data: dict[str, Any] = {}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from collections.abc import Callable
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from dateutil import parser
|
||||
|
||||
@@ -167,13 +167,11 @@ class AirNowSensor(CoordinatorEntity[AirNowDataUpdateCoordinator], SensorEntity)
|
||||
name=DEFAULT_NAME,
|
||||
)
|
||||
|
||||
@override
|
||||
@property
|
||||
def native_value(self) -> StateType:
|
||||
"""Return the state."""
|
||||
return self.entity_description.value_fn(self.coordinator.data)
|
||||
|
||||
@override
|
||||
@property
|
||||
def extra_state_attributes(self) -> dict[str, str] | None:
|
||||
"""Return the state attributes."""
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from collections.abc import Callable, Coroutine
|
||||
from dataclasses import dataclass
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from pyairobotrest.exceptions import (
|
||||
AirobotConnectionError,
|
||||
@@ -79,7 +79,6 @@ class AirobotButton(AirobotEntity, ButtonEntity):
|
||||
self.entity_description = description
|
||||
self._attr_unique_id = f"{coordinator.data.status.device_id}_{description.key}"
|
||||
|
||||
@override
|
||||
async def async_press(self) -> None:
|
||||
"""Handle the button press."""
|
||||
try:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"""Climate platform for Airobot thermostat."""
|
||||
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from pyairobotrest.const import (
|
||||
MODE_AWAY,
|
||||
@@ -77,7 +77,6 @@ class AirobotClimate(AirobotEntity, ClimateEntity):
|
||||
"""Get settings from coordinator data."""
|
||||
return self.coordinator.data.settings
|
||||
|
||||
@override
|
||||
@property
|
||||
def current_temperature(self) -> float | None:
|
||||
"""Return the current temperature.
|
||||
@@ -88,13 +87,11 @@ class AirobotClimate(AirobotEntity, ClimateEntity):
|
||||
return self._status.temp_floor
|
||||
return self._status.temp_air
|
||||
|
||||
@override
|
||||
@property
|
||||
def current_humidity(self) -> float | None:
|
||||
"""Return the current humidity."""
|
||||
return self._status.hum_air
|
||||
|
||||
@override
|
||||
@property
|
||||
def target_temperature(self) -> float | None:
|
||||
"""Return the target temperature."""
|
||||
@@ -102,7 +99,6 @@ class AirobotClimate(AirobotEntity, ClimateEntity):
|
||||
return self._settings.setpoint_temp
|
||||
return self._settings.setpoint_temp_away
|
||||
|
||||
@override
|
||||
@property
|
||||
def hvac_mode(self) -> HVACMode:
|
||||
"""Return current HVAC mode."""
|
||||
@@ -110,7 +106,6 @@ class AirobotClimate(AirobotEntity, ClimateEntity):
|
||||
return HVACMode.HEAT
|
||||
return HVACMode.OFF
|
||||
|
||||
@override
|
||||
@property
|
||||
def hvac_action(self) -> HVACAction:
|
||||
"""Return current HVAC action."""
|
||||
@@ -118,7 +113,6 @@ class AirobotClimate(AirobotEntity, ClimateEntity):
|
||||
return HVACAction.HEATING
|
||||
return HVACAction.IDLE
|
||||
|
||||
@override
|
||||
@property
|
||||
def preset_mode(self) -> str | None:
|
||||
"""Return current preset mode."""
|
||||
@@ -128,7 +122,6 @@ class AirobotClimate(AirobotEntity, ClimateEntity):
|
||||
return PRESET_HOME
|
||||
return PRESET_AWAY
|
||||
|
||||
@override
|
||||
async def async_set_temperature(self, **kwargs: Any) -> None:
|
||||
"""Set new target temperature."""
|
||||
temperature = kwargs[ATTR_TEMPERATURE]
|
||||
@@ -147,7 +140,6 @@ class AirobotClimate(AirobotEntity, ClimateEntity):
|
||||
|
||||
await self.coordinator.async_request_refresh()
|
||||
|
||||
@override
|
||||
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
|
||||
"""Set HVAC mode.
|
||||
|
||||
@@ -155,7 +147,6 @@ class AirobotClimate(AirobotEntity, ClimateEntity):
|
||||
that only supported modes are passed, so this method is a no-op.
|
||||
"""
|
||||
|
||||
@override
|
||||
async def async_set_preset_mode(self, preset_mode: str) -> None:
|
||||
"""Set new preset mode."""
|
||||
try:
|
||||
|
||||
@@ -4,7 +4,7 @@ import asyncio
|
||||
from collections.abc import Mapping
|
||||
from dataclasses import dataclass
|
||||
import logging
|
||||
from typing import Any, override
|
||||
from typing import Any
|
||||
|
||||
from pyairobotrest import AirobotClient
|
||||
from pyairobotrest.exceptions import (
|
||||
@@ -90,7 +90,6 @@ class AirobotConfigFlow(BaseConfigFlow, domain=DOMAIN):
|
||||
self._discovered_mac: str | None = None
|
||||
self._discovered_device_id: str | None = None
|
||||
|
||||
@override
|
||||
async def async_step_dhcp(
|
||||
self, discovery_info: DhcpServiceInfo
|
||||
) -> ConfigFlowResult:
|
||||
@@ -155,7 +154,6 @@ class AirobotConfigFlow(BaseConfigFlow, domain=DOMAIN):
|
||||
errors=errors,
|
||||
)
|
||||
|
||||
@override
|
||||
async def async_step_user(
|
||||
self, user_input: dict[str, Any] | None = None
|
||||
) -> ConfigFlowResult:
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user