mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 19:27:45 +00:00
2023.2.0 (#87101)
This commit is contained in:
commit
5fe3adff57
283
.coveragerc
283
.coveragerc
File diff suppressed because it is too large
Load Diff
49
.github/workflows/builder.yml
vendored
49
.github/workflows/builder.yml
vendored
@ -10,7 +10,7 @@ on:
|
||||
|
||||
env:
|
||||
BUILD_TYPE: core
|
||||
DEFAULT_PYTHON: 3.9
|
||||
DEFAULT_PYTHON: "3.10"
|
||||
|
||||
jobs:
|
||||
init:
|
||||
@ -24,12 +24,12 @@ jobs:
|
||||
publish: ${{ steps.version.outputs.publish }}
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@v3.2.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
uses: actions/setup-python@v4.4.0
|
||||
uses: actions/setup-python@v4.5.0
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
|
||||
@ -67,10 +67,10 @@ jobs:
|
||||
if: github.repository_owner == 'home-assistant' && needs.init.outputs.publish == 'true'
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@v3.2.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
uses: actions/setup-python@v4.4.0
|
||||
uses: actions/setup-python@v4.5.0
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
|
||||
@ -100,7 +100,7 @@ jobs:
|
||||
arch: ${{ fromJson(needs.init.outputs.architectures) }}
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@v3.2.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
|
||||
- name: Download nightly wheels of frontend
|
||||
if: needs.init.outputs.channel == 'dev'
|
||||
@ -113,9 +113,20 @@ jobs:
|
||||
workflow_conclusion: success
|
||||
name: wheels
|
||||
|
||||
- name: Download nightly wheels of intents
|
||||
if: needs.init.outputs.channel == 'dev'
|
||||
uses: dawidd6/action-download-artifact@v2
|
||||
with:
|
||||
github_token: ${{secrets.GITHUB_TOKEN}}
|
||||
repo: home-assistant/intents
|
||||
branch: main
|
||||
workflow: nightly.yaml
|
||||
workflow_conclusion: success
|
||||
name: package
|
||||
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
if: needs.init.outputs.channel == 'dev'
|
||||
uses: actions/setup-python@v4.4.0
|
||||
uses: actions/setup-python@v4.5.0
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
|
||||
@ -140,6 +151,24 @@ jobs:
|
||||
python -m script.gen_requirements_all
|
||||
fi
|
||||
|
||||
if [[ "$(ls home_assistant_intents*.whl)" =~ ^home_assistant_intents-(.*)-py3-none-any.whl$ ]]; then
|
||||
echo "Found intents wheel, setting version to: ${BASH_REMATCH[1]}"
|
||||
yq \
|
||||
--inplace e -o json \
|
||||
'del(.requirements[] | select(contains("home-assistant-intents")))' \
|
||||
homeassistant/components/conversation/manifest.json
|
||||
|
||||
intents_version="${BASH_REMATCH[1]}" yq \
|
||||
--inplace e -o json \
|
||||
'.requirements += ["home-assistant-intents=="+env(intents_version)]' \
|
||||
homeassistant/components/conversation/manifest.json
|
||||
|
||||
sed -i "s|home-assistant-intents==.*|home-assistant-intents==${BASH_REMATCH[1]}|" \
|
||||
homeassistant/package_constraints.txt
|
||||
|
||||
python -m script.gen_requirements_all
|
||||
fi
|
||||
|
||||
- name: Write meta info file
|
||||
shell: bash
|
||||
run: |
|
||||
@ -198,7 +227,7 @@ jobs:
|
||||
- yellow
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@v3.2.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
|
||||
- name: Set build additional args
|
||||
run: |
|
||||
@ -241,7 +270,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@v3.2.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
|
||||
- name: Initialize git
|
||||
uses: home-assistant/actions/helpers/git-init@master
|
||||
@ -280,7 +309,7 @@ jobs:
|
||||
- "homeassistant"
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@v3.2.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
|
||||
- name: Login to DockerHub
|
||||
if: matrix.registry == 'homeassistant'
|
||||
|
197
.github/workflows/ci.yaml
vendored
197
.github/workflows/ci.yaml
vendored
@ -18,13 +18,21 @@ on:
|
||||
description: "Skip pytest"
|
||||
default: false
|
||||
type: boolean
|
||||
pylint-only:
|
||||
description: "Only run pylint"
|
||||
default: false
|
||||
type: boolean
|
||||
mypy-only:
|
||||
description: "Only run mypy"
|
||||
default: false
|
||||
type: boolean
|
||||
|
||||
env:
|
||||
CACHE_VERSION: 3
|
||||
PIP_CACHE_VERSION: 3
|
||||
HA_SHORT_VERSION: 2023.1
|
||||
DEFAULT_PYTHON: 3.9
|
||||
ALL_PYTHON_VERSIONS: "['3.9', '3.10']"
|
||||
HA_SHORT_VERSION: 2023.2
|
||||
DEFAULT_PYTHON: "3.10"
|
||||
ALL_PYTHON_VERSIONS: "['3.10']"
|
||||
PRE_COMMIT_CACHE: ~/.cache/pre-commit
|
||||
PIP_CACHE: /tmp/pip-cache
|
||||
SQLALCHEMY_WARN_20: 1
|
||||
@ -56,7 +64,7 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v3.2.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
- name: Generate partial Python venv restore key
|
||||
id: generate_python_cache_key
|
||||
run: >-
|
||||
@ -163,20 +171,23 @@ jobs:
|
||||
pre-commit:
|
||||
name: Prepare pre-commit base
|
||||
runs-on: ubuntu-20.04
|
||||
if: |
|
||||
github.event.inputs.pylint-only != 'true'
|
||||
&& github.event.inputs.mypy-only != 'true'
|
||||
needs:
|
||||
- info
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v3.2.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
id: python
|
||||
uses: actions/setup-python@v4.4.0
|
||||
uses: actions/setup-python@v4.5.0
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
check-latest: true
|
||||
- name: Restore base Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache@v3.2.2
|
||||
uses: actions/cache@v3.2.3
|
||||
with:
|
||||
path: venv
|
||||
key: >-
|
||||
@ -191,7 +202,7 @@ jobs:
|
||||
pip install "$(cat requirements_test.txt | grep pre-commit)"
|
||||
- name: Restore pre-commit environment from cache
|
||||
id: cache-precommit
|
||||
uses: actions/cache@v3.2.2
|
||||
uses: actions/cache@v3.2.3
|
||||
with:
|
||||
path: ${{ env.PRE_COMMIT_CACHE }}
|
||||
key: >-
|
||||
@ -211,16 +222,16 @@ jobs:
|
||||
- pre-commit
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v3.2.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
uses: actions/setup-python@v4.4.0
|
||||
uses: actions/setup-python@v4.5.0
|
||||
id: python
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
check-latest: true
|
||||
- name: Restore base Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v3.2.2
|
||||
uses: actions/cache/restore@v3.2.3
|
||||
with:
|
||||
path: venv
|
||||
key: >-
|
||||
@ -233,7 +244,7 @@ jobs:
|
||||
exit 1
|
||||
- name: Restore pre-commit environment from cache
|
||||
id: cache-precommit
|
||||
uses: actions/cache/restore@v3.2.2
|
||||
uses: actions/cache/restore@v3.2.3
|
||||
with:
|
||||
path: ${{ env.PRE_COMMIT_CACHE }}
|
||||
key: >-
|
||||
@ -265,16 +276,16 @@ jobs:
|
||||
- pre-commit
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v3.2.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
uses: actions/setup-python@v4.4.0
|
||||
uses: actions/setup-python@v4.5.0
|
||||
id: python
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
check-latest: true
|
||||
- name: Restore base Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v3.2.2
|
||||
uses: actions/cache/restore@v3.2.3
|
||||
with:
|
||||
path: venv
|
||||
key: >-
|
||||
@ -287,7 +298,7 @@ jobs:
|
||||
exit 1
|
||||
- name: Restore pre-commit environment from cache
|
||||
id: cache-precommit
|
||||
uses: actions/cache/restore@v3.2.2
|
||||
uses: actions/cache/restore@v3.2.3
|
||||
with:
|
||||
path: ${{ env.PRE_COMMIT_CACHE }}
|
||||
key: >-
|
||||
@ -313,25 +324,24 @@ jobs:
|
||||
. venv/bin/activate
|
||||
shopt -s globstar
|
||||
pre-commit run --hook-stage manual flake8 --files {homeassistant,tests}/components/${{ needs.info.outputs.integrations_glob }}/{*,**/*}
|
||||
|
||||
lint-isort:
|
||||
name: Check isort
|
||||
runs-on: ubuntu-20.04
|
||||
lint-ruff:
|
||||
name: Check ruff
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- info
|
||||
- pre-commit
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v3.2.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
uses: actions/setup-python@v4.4.0
|
||||
uses: actions/setup-python@v4.5.0
|
||||
id: python
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
check-latest: true
|
||||
- name: Restore base Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v3.2.2
|
||||
uses: actions/cache/restore@v3.2.3
|
||||
with:
|
||||
path: venv
|
||||
key: >-
|
||||
@ -344,7 +354,63 @@ jobs:
|
||||
exit 1
|
||||
- name: Restore pre-commit environment from cache
|
||||
id: cache-precommit
|
||||
uses: actions/cache/restore@v3.2.2
|
||||
uses: actions/cache/restore@v3.2.3
|
||||
with:
|
||||
path: ${{ env.PRE_COMMIT_CACHE }}
|
||||
key: >-
|
||||
${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
|
||||
needs.info.outputs.pre-commit_cache_key }}
|
||||
- name: Fail job if pre-commit cache restore failed
|
||||
if: steps.cache-precommit.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
echo "Failed to restore pre-commit environment from cache"
|
||||
exit 1
|
||||
- name: Register ruff problem matcher
|
||||
run: |
|
||||
echo "::add-matcher::.github/workflows/matchers/ruff.json"
|
||||
- name: Run ruff (fully)
|
||||
if: needs.info.outputs.test_full_suite == 'true'
|
||||
run: |
|
||||
. venv/bin/activate
|
||||
pre-commit run --hook-stage manual ruff --all-files
|
||||
- name: Run ruff (partially)
|
||||
if: needs.info.outputs.test_full_suite == 'false'
|
||||
shell: bash
|
||||
run: |
|
||||
. venv/bin/activate
|
||||
shopt -s globstar
|
||||
pre-commit run --hook-stage manual ruff --files {homeassistant,tests}/components/${{ needs.info.outputs.integrations_glob }}/{*,**/*}
|
||||
lint-isort:
|
||||
name: Check isort
|
||||
runs-on: ubuntu-20.04
|
||||
needs:
|
||||
- info
|
||||
- pre-commit
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v3.3.0
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
uses: actions/setup-python@v4.5.0
|
||||
id: python
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
check-latest: true
|
||||
- name: Restore base Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v3.2.3
|
||||
with:
|
||||
path: venv
|
||||
key: >-
|
||||
${{ runner.os }}-${{ steps.python.outputs.python-version }}-venv-${{
|
||||
needs.info.outputs.pre-commit_cache_key }}
|
||||
- name: Fail job if Python cache restore failed
|
||||
if: steps.cache-venv.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
echo "Failed to restore Python virtual environment from cache"
|
||||
exit 1
|
||||
- name: Restore pre-commit environment from cache
|
||||
id: cache-precommit
|
||||
uses: actions/cache/restore@v3.2.3
|
||||
with:
|
||||
path: ${{ env.PRE_COMMIT_CACHE }}
|
||||
key: >-
|
||||
@ -368,16 +434,16 @@ jobs:
|
||||
- pre-commit
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v3.2.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
uses: actions/setup-python@v4.4.0
|
||||
uses: actions/setup-python@v4.5.0
|
||||
id: python
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
check-latest: true
|
||||
- name: Restore base Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v3.2.2
|
||||
uses: actions/cache/restore@v3.2.3
|
||||
with:
|
||||
path: venv
|
||||
key: >-
|
||||
@ -390,7 +456,7 @@ jobs:
|
||||
exit 1
|
||||
- name: Restore pre-commit environment from cache
|
||||
id: cache-precommit
|
||||
uses: actions/cache/restore@v3.2.2
|
||||
uses: actions/cache/restore@v3.2.3
|
||||
with:
|
||||
path: ${{ env.PRE_COMMIT_CACHE }}
|
||||
key: >-
|
||||
@ -495,10 +561,10 @@ jobs:
|
||||
python-version: ${{ fromJSON(needs.info.outputs.python_versions) }}
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v3.2.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
id: python
|
||||
uses: actions/setup-python@v4.4.0
|
||||
uses: actions/setup-python@v4.5.0
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
check-latest: true
|
||||
@ -509,7 +575,7 @@ jobs:
|
||||
env.HA_SHORT_VERSION }}-$(date -u '+%Y-%m-%dT%H:%M:%s')" >> $GITHUB_OUTPUT
|
||||
- name: Restore base Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache@v3.2.2
|
||||
uses: actions/cache@v3.2.3
|
||||
with:
|
||||
path: venv
|
||||
key: >-
|
||||
@ -517,7 +583,7 @@ jobs:
|
||||
needs.info.outputs.python_cache_key }}
|
||||
- name: Restore pip wheel cache
|
||||
if: steps.cache-venv.outputs.cache-hit != 'true'
|
||||
uses: actions/cache@v3.2.2
|
||||
uses: actions/cache@v3.2.3
|
||||
with:
|
||||
path: ${{ env.PIP_CACHE }}
|
||||
key: >-
|
||||
@ -554,21 +620,24 @@ jobs:
|
||||
hassfest:
|
||||
name: Check hassfest
|
||||
runs-on: ubuntu-20.04
|
||||
if: |
|
||||
github.event.inputs.pylint-only != 'true'
|
||||
&& github.event.inputs.mypy-only != 'true'
|
||||
needs:
|
||||
- info
|
||||
- base
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v3.2.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
id: python
|
||||
uses: actions/setup-python@v4.4.0
|
||||
uses: actions/setup-python@v4.5.0
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
check-latest: true
|
||||
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v3.2.2
|
||||
uses: actions/cache/restore@v3.2.3
|
||||
with:
|
||||
path: venv
|
||||
key: >-
|
||||
@ -587,21 +656,24 @@ jobs:
|
||||
gen-requirements-all:
|
||||
name: Check all requirements
|
||||
runs-on: ubuntu-20.04
|
||||
if: |
|
||||
github.event.inputs.pylint-only != 'true'
|
||||
&& github.event.inputs.mypy-only != 'true'
|
||||
needs:
|
||||
- info
|
||||
- base
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v3.2.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
id: python
|
||||
uses: actions/setup-python@v4.4.0
|
||||
uses: actions/setup-python@v4.5.0
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
check-latest: true
|
||||
- name: Restore base Python virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v3.2.2
|
||||
uses: actions/cache/restore@v3.2.3
|
||||
with:
|
||||
path: venv
|
||||
key: >-
|
||||
@ -621,21 +693,24 @@ jobs:
|
||||
name: Check pylint
|
||||
runs-on: ubuntu-20.04
|
||||
timeout-minutes: 20
|
||||
if: |
|
||||
github.event.inputs.mypy-only != 'true'
|
||||
|| github.event.inputs.pylint-only == 'true'
|
||||
needs:
|
||||
- info
|
||||
- base
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v3.2.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
id: python
|
||||
uses: actions/setup-python@v4.4.0
|
||||
uses: actions/setup-python@v4.5.0
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
check-latest: true
|
||||
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v3.2.2
|
||||
uses: actions/cache/restore@v3.2.3
|
||||
with:
|
||||
path: venv
|
||||
key: >-
|
||||
@ -666,21 +741,24 @@ jobs:
|
||||
mypy:
|
||||
name: Check mypy
|
||||
runs-on: ubuntu-20.04
|
||||
if: |
|
||||
github.event.inputs.pylint-only != 'true'
|
||||
|| github.event.inputs.mypy-only == 'true'
|
||||
needs:
|
||||
- info
|
||||
- base
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v3.2.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
id: python
|
||||
uses: actions/setup-python@v4.4.0
|
||||
uses: actions/setup-python@v4.5.0
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
check-latest: true
|
||||
- name: Restore full Python ${{ env.DEFAULT_PYTHON }} virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v3.2.2
|
||||
uses: actions/cache/restore@v3.2.3
|
||||
with:
|
||||
path: venv
|
||||
key: >-
|
||||
@ -710,6 +788,9 @@ jobs:
|
||||
|
||||
pip-check:
|
||||
runs-on: ubuntu-20.04
|
||||
if: |
|
||||
github.event.inputs.pylint-only != 'true'
|
||||
&& github.event.inputs.mypy-only != 'true'
|
||||
needs:
|
||||
- info
|
||||
- base
|
||||
@ -720,16 +801,16 @@ jobs:
|
||||
name: Run pip check ${{ matrix.python-version }}
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v3.2.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
id: python
|
||||
uses: actions/setup-python@v4.4.0
|
||||
uses: actions/setup-python@v4.5.0
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
check-latest: true
|
||||
- name: Restore full Python ${{ matrix.python-version }} virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v3.2.2
|
||||
uses: actions/cache/restore@v3.2.3
|
||||
with:
|
||||
path: venv
|
||||
key: >-
|
||||
@ -750,6 +831,8 @@ jobs:
|
||||
if: |
|
||||
(github.event_name != 'push' || github.event.repository.full_name == 'home-assistant/core')
|
||||
&& github.event.inputs.lint-only != 'true'
|
||||
&& github.event.inputs.pylint-only != 'true'
|
||||
&& github.event.inputs.mypy-only != 'true'
|
||||
&& (needs.info.outputs.test_full_suite == 'true' || needs.info.outputs.tests_glob)
|
||||
needs:
|
||||
- info
|
||||
@ -775,16 +858,16 @@ jobs:
|
||||
bluez \
|
||||
ffmpeg
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v3.2.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
id: python
|
||||
uses: actions/setup-python@v4.4.0
|
||||
uses: actions/setup-python@v4.5.0
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
check-latest: true
|
||||
- name: Restore full Python ${{ matrix.python-version }} virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v3.2.2
|
||||
uses: actions/cache/restore@v3.2.3
|
||||
with:
|
||||
path: venv
|
||||
key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
|
||||
@ -852,7 +935,7 @@ jobs:
|
||||
-p no:sugar \
|
||||
tests/components/${{ matrix.group }}
|
||||
- name: Upload coverage artifact
|
||||
uses: actions/upload-artifact@v3.1.1
|
||||
uses: actions/upload-artifact@v3.1.2
|
||||
with:
|
||||
name: coverage-${{ matrix.python-version }}-${{ matrix.group }}
|
||||
path: coverage.xml
|
||||
@ -873,6 +956,8 @@ jobs:
|
||||
if: |
|
||||
(github.event_name != 'push' || github.event.repository.full_name == 'home-assistant/core')
|
||||
&& github.event.inputs.lint-only != 'true'
|
||||
&& github.event.inputs.pylint-only != 'true'
|
||||
&& github.event.inputs.mypy-only != 'true'
|
||||
&& needs.info.outputs.test_full_suite == 'true'
|
||||
needs:
|
||||
- info
|
||||
@ -898,16 +983,16 @@ jobs:
|
||||
ffmpeg \
|
||||
libmariadb-dev-compat
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v3.2.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
- name: Set up Python ${{ matrix.python-version }}
|
||||
id: python
|
||||
uses: actions/setup-python@v4.4.0
|
||||
uses: actions/setup-python@v4.5.0
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
check-latest: true
|
||||
- name: Restore full Python ${{ matrix.python-version }} virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache/restore@v3.2.2
|
||||
uses: actions/cache/restore@v3.2.3
|
||||
with:
|
||||
path: venv
|
||||
key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
|
||||
@ -954,7 +1039,7 @@ jobs:
|
||||
--dburl=mysql://root:password@127.0.0.1/homeassistant-test \
|
||||
tests/components/recorder
|
||||
- name: Upload coverage artifact
|
||||
uses: actions/upload-artifact@v3.1.1
|
||||
uses: actions/upload-artifact@v3.1.2
|
||||
with:
|
||||
name: coverage-${{ matrix.python-version }}-mariadb
|
||||
path: coverage.xml
|
||||
@ -970,7 +1055,7 @@ jobs:
|
||||
- pytest
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v3.2.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
- name: Download all coverage artifacts
|
||||
uses: actions/download-artifact@v3
|
||||
- name: Upload coverage to Codecov (full coverage)
|
||||
|
30
.github/workflows/matchers/ruff.json
vendored
Normal file
30
.github/workflows/matchers/ruff.json
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
{
|
||||
"problemMatcher": [
|
||||
{
|
||||
"owner": "ruff-error",
|
||||
"severity": "error",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "^(.*):(\\d+):(\\d+):\\s([EF]\\d{3}\\s.*)$",
|
||||
"file": 1,
|
||||
"line": 2,
|
||||
"column": 3,
|
||||
"message": 4
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"owner": "ruff-warning",
|
||||
"severity": "warning",
|
||||
"pattern": [
|
||||
{
|
||||
"regexp": "^(.*):(\\d+):(\\d+):\\s([CDNW]\\d{3}\\s.*)$",
|
||||
"file": 1,
|
||||
"line": 2,
|
||||
"column": 3,
|
||||
"message": 4
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
83
.github/workflows/stale.yml
vendored
83
.github/workflows/stale.yml
vendored
@ -11,34 +11,21 @@ jobs:
|
||||
if: github.repository_owner == 'home-assistant'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# The 90 day stale policy
|
||||
# The 90 day stale policy for PRs
|
||||
# Used for:
|
||||
# - Issues & PRs
|
||||
# - PRs
|
||||
# - No PRs marked as no-stale
|
||||
# - No issues marked as no-stale or help-wanted
|
||||
- name: 90 days stale issues & PRs policy
|
||||
# - No issues (-1)
|
||||
- name: 90 days stale PRs policy
|
||||
uses: actions/stale@v7.0.0
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 90
|
||||
days-before-close: 7
|
||||
days-before-issue-stale: -1
|
||||
days-before-issue-close: -1
|
||||
operations-per-run: 150
|
||||
remove-stale-when-updated: true
|
||||
stale-issue-label: "stale"
|
||||
exempt-issue-labels: "no-stale,help-wanted"
|
||||
stale-issue-message: >
|
||||
There hasn't been any activity on this issue recently. Due to the
|
||||
high number of incoming GitHub notifications, we have to clean some
|
||||
of the old issues, as many of them have already been resolved with
|
||||
the latest updates.
|
||||
|
||||
Please make sure to update to the latest Home Assistant version and
|
||||
check if that solves the issue. Let us know if that works for you by
|
||||
adding a comment 👍
|
||||
|
||||
This issue has now been marked as stale and will be closed if no
|
||||
further activity occurs. Thank you for your contributions.
|
||||
|
||||
stale-pr-label: "stale"
|
||||
exempt-pr-labels: "no-stale"
|
||||
stale-pr-message: >
|
||||
@ -48,30 +35,47 @@ jobs:
|
||||
|
||||
Thank you for your contributions.
|
||||
|
||||
# The 30 day stale policy for PRS
|
||||
# Generate a token for the GitHub App, we use this method to avoid
|
||||
# hitting API limits for our GitHub actions + have a higher rate limit.
|
||||
# This is only used for issues.
|
||||
- name: Generate app token
|
||||
id: token
|
||||
# Pinned to a specific version of the action for security reasons
|
||||
# v1.7.0
|
||||
uses: tibdex/github-app-token@021a2405c7f990db57f5eae5397423dcc554159c
|
||||
with:
|
||||
app_id: ${{ secrets.ISSUE_TRIAGE_APP_ID }}
|
||||
private_key: ${{ secrets.ISSUE_TRIAGE_APP_PEM }}
|
||||
|
||||
# The 90 day stale policy for issues
|
||||
# Used for:
|
||||
# - PRs
|
||||
# - No PRs marked as no-stale or new-integrations
|
||||
# - No issues (-1)
|
||||
- name: 30 days stale PRs policy
|
||||
# - Issues
|
||||
# - No issues marked as no-stale or help-wanted
|
||||
# - No PRs (-1)
|
||||
- name: 90 days stale issues
|
||||
uses: actions/stale@v7.0.0
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 30
|
||||
repo-token: ${{ steps.token.outputs.token }}
|
||||
days-before-stale: 90
|
||||
days-before-close: 7
|
||||
days-before-issue-close: -1
|
||||
operations-per-run: 50
|
||||
days-before-pr-stale: -1
|
||||
days-before-pr-close: -1
|
||||
operations-per-run: 250
|
||||
remove-stale-when-updated: true
|
||||
stale-pr-label: "stale"
|
||||
# Exempt new integrations, these often take more time.
|
||||
# They will automatically be handled by the 90 day version above.
|
||||
exempt-pr-labels: "no-stale,new-integration"
|
||||
stale-pr-message: >
|
||||
There hasn't been any activity on this pull request recently. This
|
||||
pull request has been automatically marked as stale because of that
|
||||
and will be closed if no further activity occurs within 7 days.
|
||||
stale-issue-label: "stale"
|
||||
exempt-issue-labels: "no-stale,help-wanted,needs-more-information"
|
||||
stale-issue-message: >
|
||||
There hasn't been any activity on this issue recently. Due to the
|
||||
high number of incoming GitHub notifications, we have to clean some
|
||||
of the old issues, as many of them have already been resolved with
|
||||
the latest updates.
|
||||
|
||||
Thank you for your contributions.
|
||||
Please make sure to update to the latest Home Assistant version and
|
||||
check if that solves the issue. Let us know if that works for you by
|
||||
adding a comment 👍
|
||||
|
||||
This issue has now been marked as stale and will be closed if no
|
||||
further activity occurs. Thank you for your contributions.
|
||||
|
||||
# The 30 day stale policy for issues
|
||||
# Used for:
|
||||
@ -81,12 +85,13 @@ jobs:
|
||||
- name: Needs more information stale issues policy
|
||||
uses: actions/stale@v7.0.0
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
repo-token: ${{ steps.token.outputs.token }}
|
||||
only-labels: "needs-more-information"
|
||||
days-before-stale: 14
|
||||
days-before-close: 7
|
||||
days-before-pr-stale: -1
|
||||
days-before-pr-close: -1
|
||||
operations-per-run: 50
|
||||
operations-per-run: 250
|
||||
remove-stale-when-updated: true
|
||||
stale-issue-label: "stale"
|
||||
exempt-issue-labels: "no-stale,help-wanted"
|
||||
|
10
.github/workflows/translations.yaml
vendored
10
.github/workflows/translations.yaml
vendored
@ -12,7 +12,7 @@ on:
|
||||
- "**strings.json"
|
||||
|
||||
env:
|
||||
DEFAULT_PYTHON: 3.9
|
||||
DEFAULT_PYTHON: "3.10"
|
||||
|
||||
jobs:
|
||||
upload:
|
||||
@ -21,10 +21,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@v3.2.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
uses: actions/setup-python@v4.4.0
|
||||
uses: actions/setup-python@v4.5.0
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
|
||||
@ -40,10 +40,10 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@v3.2.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
uses: actions/setup-python@v4.4.0
|
||||
uses: actions/setup-python@v4.5.0
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
|
||||
|
37
.github/workflows/wheels.yml
vendored
37
.github/workflows/wheels.yml
vendored
@ -22,7 +22,7 @@ jobs:
|
||||
architectures: ${{ steps.info.outputs.architectures }}
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@v3.2.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
|
||||
- name: Get information
|
||||
id: info
|
||||
@ -57,13 +57,13 @@ jobs:
|
||||
) > .env_file
|
||||
|
||||
- name: Upload env_file
|
||||
uses: actions/upload-artifact@v3.1.1
|
||||
uses: actions/upload-artifact@v3.1.2
|
||||
with:
|
||||
name: env_file
|
||||
path: ./.env_file
|
||||
|
||||
- name: Upload requirements_diff
|
||||
uses: actions/upload-artifact@v3.1.1
|
||||
uses: actions/upload-artifact@v3.1.2
|
||||
with:
|
||||
name: requirements_diff
|
||||
path: ./requirements_diff.txt
|
||||
@ -79,7 +79,7 @@ jobs:
|
||||
arch: ${{ fromJson(needs.init.outputs.architectures) }}
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@v3.2.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
|
||||
- name: Download env_file
|
||||
uses: actions/download-artifact@v3
|
||||
@ -116,7 +116,7 @@ jobs:
|
||||
arch: ${{ fromJson(needs.init.outputs.architectures) }}
|
||||
steps:
|
||||
- name: Checkout the repository
|
||||
uses: actions/checkout@v3.2.0
|
||||
uses: actions/checkout@v3.3.0
|
||||
|
||||
- name: Download env_file
|
||||
uses: actions/download-artifact@v3
|
||||
@ -144,6 +144,14 @@ jobs:
|
||||
sed -i "s|# opencv-python-headless|opencv-python-headless|g" ${requirement_file}
|
||||
done
|
||||
|
||||
- name: Split requirements all
|
||||
run: |
|
||||
# We split requirements all into two different files.
|
||||
# This is to prevent the build from running out of memory when
|
||||
# resolving packages on 32-bits systems (like armhf, armv7).
|
||||
|
||||
split -l $(expr $(expr $(cat requirements_all.txt | wc -l) + 1) / 2) requirements_all.txt requirements_all.txt
|
||||
|
||||
- name: Adjust build env
|
||||
run: |
|
||||
if [ "${{ matrix.arch }}" = "i386" ]; then
|
||||
@ -159,7 +167,7 @@ jobs:
|
||||
# Do not pin numpy in wheels building
|
||||
sed -i "/numpy/d" homeassistant/package_constraints.txt
|
||||
|
||||
- name: Build wheels
|
||||
- name: Build wheels (part 1)
|
||||
uses: home-assistant/wheels@2022.10.1
|
||||
with:
|
||||
abi: cp310
|
||||
@ -172,4 +180,19 @@ jobs:
|
||||
legacy: true
|
||||
constraints: "homeassistant/package_constraints.txt"
|
||||
requirements-diff: "requirements_diff.txt"
|
||||
requirements: "requirements_all.txt"
|
||||
requirements: "requirements_all.txtaa"
|
||||
|
||||
- name: Build wheels (part 2)
|
||||
uses: home-assistant/wheels@2022.10.1
|
||||
with:
|
||||
abi: cp310
|
||||
tag: musllinux_1_2
|
||||
arch: ${{ matrix.arch }}
|
||||
wheels-key: ${{ secrets.WHEELS_KEY }}
|
||||
env-file: true
|
||||
apk: "libexecinfo-dev;bluez-dev;libffi-dev;openssl-dev;glib-dev;eudev-dev;libxml2-dev;libxslt-dev;libpng-dev;libjpeg-turbo-dev;tiff-dev;cups-dev;gmp-dev;mpfr-dev;mpc1-dev;ffmpeg-dev;gammu-dev;yaml-dev;openblas-dev;fftw-dev;lapack-dev;gfortran;blas-dev;eigen-dev;freetype-dev;glew-dev;harfbuzz-dev;hdf5-dev;libdc1394-dev;libtbb-dev;mesa-dev;openexr-dev;openjpeg-dev"
|
||||
skip-binary: aiohttp;grpcio
|
||||
legacy: true
|
||||
constraints: "homeassistant/package_constraints.txt"
|
||||
requirements-diff: "requirements_diff.txt"
|
||||
requirements: "requirements_all.txtab"
|
||||
|
@ -1,9 +1,16 @@
|
||||
repos:
|
||||
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
||||
rev: v0.0.231
|
||||
hooks:
|
||||
- id: ruff
|
||||
args:
|
||||
- --fix
|
||||
- repo: https://github.com/asottile/pyupgrade
|
||||
rev: v3.3.1
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args: [--py39-plus]
|
||||
args: [--py310-plus]
|
||||
stages: [manual]
|
||||
- repo: https://github.com/PyCQA/autoflake
|
||||
rev: v2.0.0
|
||||
hooks:
|
||||
@ -11,6 +18,7 @@ repos:
|
||||
args:
|
||||
- --in-place
|
||||
- --remove-all-unused-imports
|
||||
stages: [manual]
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 22.12.0
|
||||
hooks:
|
||||
@ -36,11 +44,12 @@ repos:
|
||||
- pycodestyle==2.10.0
|
||||
- pyflakes==3.0.1
|
||||
- flake8-docstrings==1.6.0
|
||||
- pydocstyle==6.1.1
|
||||
- pydocstyle==6.2.3
|
||||
- flake8-comprehensions==3.10.1
|
||||
- flake8-noqa==1.3.0
|
||||
- mccabe==0.7.0
|
||||
files: ^(homeassistant|script|tests)/.+\.py$
|
||||
exclude: docs/source/conf.py
|
||||
stages: [manual]
|
||||
- repo: https://github.com/PyCQA/bandit
|
||||
rev: 1.7.4
|
||||
hooks:
|
||||
@ -51,11 +60,11 @@ repos:
|
||||
- --configfile=tests/bandit.yaml
|
||||
files: ^(homeassistant|script|tests)/.+\.py$
|
||||
- repo: https://github.com/PyCQA/isort
|
||||
rev: 5.11.4
|
||||
rev: 5.12.0
|
||||
hooks:
|
||||
- id: isort
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v3.2.0
|
||||
rev: v4.4.0
|
||||
hooks:
|
||||
- id: check-executables-have-shebangs
|
||||
stages: [manual]
|
||||
@ -84,7 +93,7 @@ repos:
|
||||
- id: python-typing-update
|
||||
stages: [manual]
|
||||
args:
|
||||
- --py39-plus
|
||||
- --py310-plus
|
||||
- --force
|
||||
- --keep-updates
|
||||
files: ^(homeassistant|tests|script)/.+\.py$
|
||||
|
@ -58,6 +58,7 @@ homeassistant.components.amcrest.*
|
||||
homeassistant.components.ampio.*
|
||||
homeassistant.components.analytics.*
|
||||
homeassistant.components.anthemav.*
|
||||
homeassistant.components.apcupsd.*
|
||||
homeassistant.components.aqualogic.*
|
||||
homeassistant.components.aseko_pool_live.*
|
||||
homeassistant.components.asuswrt.*
|
||||
@ -68,6 +69,7 @@ homeassistant.components.backup.*
|
||||
homeassistant.components.baf.*
|
||||
homeassistant.components.bayesian.*
|
||||
homeassistant.components.binary_sensor.*
|
||||
homeassistant.components.bitcoin.*
|
||||
homeassistant.components.blockchain.*
|
||||
homeassistant.components.bluetooth.*
|
||||
homeassistant.components.bluetooth_tracker.*
|
||||
@ -110,6 +112,7 @@ homeassistant.components.fastdotcom.*
|
||||
homeassistant.components.feedreader.*
|
||||
homeassistant.components.file_upload.*
|
||||
homeassistant.components.filesize.*
|
||||
homeassistant.components.filter.*
|
||||
homeassistant.components.fitbit.*
|
||||
homeassistant.components.flux_led.*
|
||||
homeassistant.components.forecast_solar.*
|
||||
@ -172,10 +175,12 @@ homeassistant.components.jewish_calendar.*
|
||||
homeassistant.components.kaleidescape.*
|
||||
homeassistant.components.knx.*
|
||||
homeassistant.components.kraken.*
|
||||
homeassistant.components.lacrosse.*
|
||||
homeassistant.components.lacrosse_view.*
|
||||
homeassistant.components.lametric.*
|
||||
homeassistant.components.laundrify.*
|
||||
homeassistant.components.lcn.*
|
||||
homeassistant.components.ld2410_ble.*
|
||||
homeassistant.components.lidarr.*
|
||||
homeassistant.components.lifx.*
|
||||
homeassistant.components.light.*
|
||||
@ -198,6 +203,7 @@ homeassistant.components.mjpeg.*
|
||||
homeassistant.components.modbus.*
|
||||
homeassistant.components.modem_callerid.*
|
||||
homeassistant.components.moon.*
|
||||
homeassistant.components.mopeka.*
|
||||
homeassistant.components.mqtt.*
|
||||
homeassistant.components.mysensors.*
|
||||
homeassistant.components.nam.*
|
||||
@ -219,6 +225,7 @@ homeassistant.components.onewire.*
|
||||
homeassistant.components.open_meteo.*
|
||||
homeassistant.components.openexchangerates.*
|
||||
homeassistant.components.openuv.*
|
||||
homeassistant.components.otbr.*
|
||||
homeassistant.components.overkiz.*
|
||||
homeassistant.components.peco.*
|
||||
homeassistant.components.persistent_notification.*
|
||||
@ -245,17 +252,21 @@ homeassistant.components.ridwell.*
|
||||
homeassistant.components.rituals_perfume_genie.*
|
||||
homeassistant.components.roku.*
|
||||
homeassistant.components.rpi_power.*
|
||||
homeassistant.components.rss_feed_template.*
|
||||
homeassistant.components.rtsp_to_webrtc.*
|
||||
homeassistant.components.ruuvi_gateway.*
|
||||
homeassistant.components.ruuvitag_ble.*
|
||||
homeassistant.components.samsungtv.*
|
||||
homeassistant.components.scene.*
|
||||
homeassistant.components.schedule.*
|
||||
homeassistant.components.scrape.*
|
||||
homeassistant.components.select.*
|
||||
homeassistant.components.senseme.*
|
||||
homeassistant.components.sensibo.*
|
||||
homeassistant.components.sensirion_ble.*
|
||||
homeassistant.components.sensor.*
|
||||
homeassistant.components.senz.*
|
||||
homeassistant.components.sfr_box.*
|
||||
homeassistant.components.shelly.*
|
||||
homeassistant.components.simplepush.*
|
||||
homeassistant.components.simplisafe.*
|
||||
|
14
.vscode/tasks.json
vendored
14
.vscode/tasks.json
vendored
@ -41,6 +41,20 @@
|
||||
},
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Ruff",
|
||||
"type": "shell",
|
||||
"command": "pre-commit run ruff --all-files",
|
||||
"group": {
|
||||
"kind": "test",
|
||||
"isDefault": true
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "always",
|
||||
"panel": "new"
|
||||
},
|
||||
"problemMatcher": []
|
||||
},
|
||||
{
|
||||
"label": "Pylint",
|
||||
"type": "shell",
|
||||
|
59
CODEOWNERS
59
CODEOWNERS
@ -67,8 +67,6 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/alert/ @home-assistant/core @frenck
|
||||
/homeassistant/components/alexa/ @home-assistant/cloud @ochlocracy @jbouwh
|
||||
/tests/components/alexa/ @home-assistant/cloud @ochlocracy @jbouwh
|
||||
/homeassistant/components/almond/ @gcampax @balloob
|
||||
/tests/components/almond/ @gcampax @balloob
|
||||
/homeassistant/components/amberelectric/ @madpilot
|
||||
/tests/components/amberelectric/ @madpilot
|
||||
/homeassistant/components/ambiclimate/ @danielhiversen
|
||||
@ -156,6 +154,8 @@ build.json @home-assistant/supervisor
|
||||
/homeassistant/components/bluesound/ @thrawnarn
|
||||
/homeassistant/components/bluetooth/ @bdraco
|
||||
/tests/components/bluetooth/ @bdraco
|
||||
/homeassistant/components/bluetooth_adapters/ @bdraco
|
||||
/tests/components/bluetooth_adapters/ @bdraco
|
||||
/homeassistant/components/bmw_connected_drive/ @gerard33 @rikroe
|
||||
/tests/components/bmw_connected_drive/ @gerard33 @rikroe
|
||||
/homeassistant/components/bond/ @bdraco @prystupa @joshs85 @marciogranzotto
|
||||
@ -265,6 +265,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/discord/ @tkdrob
|
||||
/homeassistant/components/discovery/ @home-assistant/core
|
||||
/tests/components/discovery/ @home-assistant/core
|
||||
/homeassistant/components/dlink/ @tkdrob
|
||||
/tests/components/dlink/ @tkdrob
|
||||
/homeassistant/components/dlna_dmr/ @StevenLooman @chishm
|
||||
/tests/components/dlna_dmr/ @StevenLooman @chishm
|
||||
/homeassistant/components/dlna_dms/ @chishm
|
||||
@ -313,6 +315,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/emulated_kasa/ @kbickar
|
||||
/homeassistant/components/energy/ @home-assistant/core
|
||||
/tests/components/energy/ @home-assistant/core
|
||||
/homeassistant/components/energyzero/ @klaasnicolaas
|
||||
/tests/components/energyzero/ @klaasnicolaas
|
||||
/homeassistant/components/enigma2/ @fbradyirl
|
||||
/homeassistant/components/enocean/ @bdurrer
|
||||
/tests/components/enocean/ @bdurrer
|
||||
@ -331,6 +335,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/escea/ @lazdavila
|
||||
/homeassistant/components/esphome/ @OttoWinter @jesserockz
|
||||
/tests/components/esphome/ @OttoWinter @jesserockz
|
||||
/homeassistant/components/eufylife_ble/ @bdr99
|
||||
/tests/components/eufylife_ble/ @bdr99
|
||||
/homeassistant/components/evil_genius_labs/ @balloob
|
||||
/tests/components/evil_genius_labs/ @balloob
|
||||
/homeassistant/components/evohome/ @zxdavb
|
||||
@ -433,6 +439,8 @@ build.json @home-assistant/supervisor
|
||||
/homeassistant/components/google_assistant_sdk/ @tronikos
|
||||
/tests/components/google_assistant_sdk/ @tronikos
|
||||
/homeassistant/components/google_cloud/ @lufton
|
||||
/homeassistant/components/google_mail/ @tkdrob
|
||||
/tests/components/google_mail/ @tkdrob
|
||||
/homeassistant/components/google_sheets/ @tkdrob
|
||||
/tests/components/google_sheets/ @tkdrob
|
||||
/homeassistant/components/google_travel_time/ @eifinger
|
||||
@ -499,8 +507,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/homematic/ @pvizeli @danielperna84
|
||||
/homeassistant/components/homewizard/ @DCSBL
|
||||
/tests/components/homewizard/ @DCSBL
|
||||
/homeassistant/components/honeywell/ @rdfurman
|
||||
/tests/components/honeywell/ @rdfurman
|
||||
/homeassistant/components/honeywell/ @rdfurman @mkmer
|
||||
/tests/components/honeywell/ @rdfurman @mkmer
|
||||
/homeassistant/components/http/ @home-assistant/core
|
||||
/tests/components/http/ @home-assistant/core
|
||||
/homeassistant/components/huawei_lte/ @scop @fphammerle
|
||||
@ -533,6 +541,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/image_processing/ @home-assistant/core
|
||||
/homeassistant/components/image_upload/ @home-assistant/core
|
||||
/tests/components/image_upload/ @home-assistant/core
|
||||
/homeassistant/components/imap/ @engrbm87
|
||||
/tests/components/imap/ @engrbm87
|
||||
/homeassistant/components/incomfort/ @zxdavb
|
||||
/homeassistant/components/influxdb/ @mdegat01
|
||||
/tests/components/influxdb/ @mdegat01
|
||||
@ -599,6 +609,8 @@ build.json @home-assistant/supervisor
|
||||
/homeassistant/components/keyboard_remote/ @bendavid @lanrat
|
||||
/homeassistant/components/keymitt_ble/ @spycle
|
||||
/tests/components/keymitt_ble/ @spycle
|
||||
/homeassistant/components/kitchen_sink/ @home-assistant/core
|
||||
/tests/components/kitchen_sink/ @home-assistant/core
|
||||
/homeassistant/components/kmtronic/ @dgomes
|
||||
/tests/components/kmtronic/ @dgomes
|
||||
/homeassistant/components/knx/ @Julius2342 @farmio @marvin-w
|
||||
@ -625,6 +637,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/laundrify/ @xLarry
|
||||
/homeassistant/components/lcn/ @alengwenus
|
||||
/tests/components/lcn/ @alengwenus
|
||||
/homeassistant/components/ld2410_ble/ @930913
|
||||
/tests/components/ld2410_ble/ @930913
|
||||
/homeassistant/components/led_ble/ @bdraco
|
||||
/tests/components/led_ble/ @bdraco
|
||||
/homeassistant/components/lg_netcast/ @Drafteed
|
||||
@ -669,7 +683,6 @@ build.json @home-assistant/supervisor
|
||||
/homeassistant/components/lyric/ @timmo001
|
||||
/tests/components/lyric/ @timmo001
|
||||
/homeassistant/components/mastodon/ @fabaff
|
||||
/homeassistant/components/matrix/ @tinloaf
|
||||
/homeassistant/components/matter/ @home-assistant/matter
|
||||
/tests/components/matter/ @home-assistant/matter
|
||||
/homeassistant/components/mazda/ @bdr99
|
||||
@ -725,6 +738,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/monoprice/ @etsinko @OnFreund
|
||||
/homeassistant/components/moon/ @fabaff @frenck
|
||||
/tests/components/moon/ @fabaff @frenck
|
||||
/homeassistant/components/mopeka/ @bdraco
|
||||
/tests/components/mopeka/ @bdraco
|
||||
/homeassistant/components/motion_blinds/ @starkillerOG
|
||||
/tests/components/motion_blinds/ @starkillerOG
|
||||
/homeassistant/components/motioneye/ @dermotduffy
|
||||
@ -825,6 +840,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/onvif/ @hunterjm
|
||||
/homeassistant/components/open_meteo/ @frenck
|
||||
/tests/components/open_meteo/ @frenck
|
||||
/homeassistant/components/openai_conversation/ @balloob
|
||||
/tests/components/openai_conversation/ @balloob
|
||||
/homeassistant/components/openerz/ @misialq
|
||||
/tests/components/openerz/ @misialq
|
||||
/homeassistant/components/openexchangerates/ @MartinHjelmare
|
||||
@ -840,9 +857,11 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/openweathermap/ @fabaff @freekode @nzapponi
|
||||
/homeassistant/components/opnsense/ @mtreinish
|
||||
/tests/components/opnsense/ @mtreinish
|
||||
/homeassistant/components/oralb/ @bdraco
|
||||
/tests/components/oralb/ @bdraco
|
||||
/homeassistant/components/oralb/ @bdraco @Lash-L
|
||||
/tests/components/oralb/ @bdraco @Lash-L
|
||||
/homeassistant/components/oru/ @bvlaicu
|
||||
/homeassistant/components/otbr/ @home-assistant/core
|
||||
/tests/components/otbr/ @home-assistant/core
|
||||
/homeassistant/components/overkiz/ @imicknl @vlebourl @tetienne @nyroDev
|
||||
/tests/components/overkiz/ @imicknl @vlebourl @tetienne @nyroDev
|
||||
/homeassistant/components/ovo_energy/ @timmo001
|
||||
@ -877,8 +896,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/point/ @fredrike
|
||||
/homeassistant/components/poolsense/ @haemishkyd
|
||||
/tests/components/poolsense/ @haemishkyd
|
||||
/homeassistant/components/powerwall/ @bdraco @jrester
|
||||
/tests/components/powerwall/ @bdraco @jrester
|
||||
/homeassistant/components/powerwall/ @bdraco @jrester @daniel-simpson
|
||||
/tests/components/powerwall/ @bdraco @jrester @daniel-simpson
|
||||
/homeassistant/components/profiler/ @bdraco
|
||||
/tests/components/profiler/ @bdraco
|
||||
/homeassistant/components/progettihwsw/ @ardaseremet
|
||||
@ -980,8 +999,12 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/rtsp_to_webrtc/ @allenporter
|
||||
/homeassistant/components/ruckus_unleashed/ @gabe565
|
||||
/tests/components/ruckus_unleashed/ @gabe565
|
||||
/homeassistant/components/ruuvi_gateway/ @akx
|
||||
/tests/components/ruuvi_gateway/ @akx
|
||||
/homeassistant/components/ruuvitag_ble/ @akx
|
||||
/tests/components/ruuvitag_ble/ @akx
|
||||
/homeassistant/components/rympro/ @OnFreund
|
||||
/tests/components/rympro/ @OnFreund
|
||||
/homeassistant/components/sabnzbd/ @shaiu
|
||||
/tests/components/sabnzbd/ @shaiu
|
||||
/homeassistant/components/safe_mode/ @home-assistant/core
|
||||
@ -1026,6 +1049,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/senz/ @milanmeu
|
||||
/homeassistant/components/serial/ @fabaff
|
||||
/homeassistant/components/seven_segments/ @fabaff
|
||||
/homeassistant/components/sfr_box/ @epenet
|
||||
/tests/components/sfr_box/ @epenet
|
||||
/homeassistant/components/sharkiq/ @JeffResc @funkybunch @AritroSaha10
|
||||
/tests/components/sharkiq/ @JeffResc @funkybunch @AritroSaha10
|
||||
/homeassistant/components/shell_command/ @home-assistant/core
|
||||
@ -1107,6 +1132,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/srp_energy/ @briglx
|
||||
/homeassistant/components/starline/ @anonym-tsk
|
||||
/tests/components/starline/ @anonym-tsk
|
||||
/homeassistant/components/starlink/ @boswelja
|
||||
/tests/components/starlink/ @boswelja
|
||||
/homeassistant/components/statistics/ @fabaff @ThomDietrich
|
||||
/tests/components/statistics/ @fabaff @ThomDietrich
|
||||
/homeassistant/components/steam_online/ @tkdrob
|
||||
@ -1116,6 +1143,8 @@ build.json @home-assistant/supervisor
|
||||
/homeassistant/components/stiebel_eltron/ @fucm
|
||||
/homeassistant/components/stookalert/ @fwestenberg @frenck
|
||||
/tests/components/stookalert/ @fwestenberg @frenck
|
||||
/homeassistant/components/stookwijzer/ @fwestenberg
|
||||
/tests/components/stookwijzer/ @fwestenberg
|
||||
/homeassistant/components/stream/ @hunterjm @uvjustin @allenporter
|
||||
/tests/components/stream/ @hunterjm @uvjustin @allenporter
|
||||
/homeassistant/components/stt/ @pvizeli
|
||||
@ -1177,6 +1206,8 @@ build.json @home-assistant/supervisor
|
||||
/homeassistant/components/thermopro/ @bdraco
|
||||
/tests/components/thermopro/ @bdraco
|
||||
/homeassistant/components/thethingsnetwork/ @fabaff
|
||||
/homeassistant/components/thread/ @home-assistant/core
|
||||
/tests/components/thread/ @home-assistant/core
|
||||
/homeassistant/components/threshold/ @fabaff
|
||||
/tests/components/threshold/ @fabaff
|
||||
/homeassistant/components/tibber/ @danielhiversen
|
||||
@ -1299,8 +1330,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/websocket_api/ @home-assistant/core
|
||||
/homeassistant/components/wemo/ @esev
|
||||
/tests/components/wemo/ @esev
|
||||
/homeassistant/components/whirlpool/ @abmantis
|
||||
/tests/components/whirlpool/ @abmantis
|
||||
/homeassistant/components/whirlpool/ @abmantis @mkmer
|
||||
/tests/components/whirlpool/ @abmantis @mkmer
|
||||
/homeassistant/components/whois/ @frenck
|
||||
/tests/components/whois/ @frenck
|
||||
/homeassistant/components/wiffi/ @mampfes
|
||||
@ -1356,6 +1387,8 @@ build.json @home-assistant/supervisor
|
||||
/tests/components/zeroconf/ @bdraco
|
||||
/homeassistant/components/zerproc/ @emlove
|
||||
/tests/components/zerproc/ @emlove
|
||||
/homeassistant/components/zeversolar/ @kvanzuijlen
|
||||
/tests/components/zeversolar/ @kvanzuijlen
|
||||
/homeassistant/components/zha/ @dmulcahey @adminiuga @puddly
|
||||
/tests/components/zha/ @dmulcahey @adminiuga @puddly
|
||||
/homeassistant/components/zodiac/ @JulienTant
|
||||
@ -1365,8 +1398,8 @@ build.json @home-assistant/supervisor
|
||||
/homeassistant/components/zoneminder/ @rohankapoorcom
|
||||
/homeassistant/components/zwave_js/ @home-assistant/z-wave
|
||||
/tests/components/zwave_js/ @home-assistant/z-wave
|
||||
/homeassistant/components/zwave_me/ @lawfulchaos @Z-Wave-Me
|
||||
/tests/components/zwave_me/ @lawfulchaos @Z-Wave-Me
|
||||
/homeassistant/components/zwave_me/ @lawfulchaos @Z-Wave-Me @PoltoS
|
||||
/tests/components/zwave_me/ @lawfulchaos @Z-Wave-Me @PoltoS
|
||||
|
||||
# Individual files
|
||||
/homeassistant/components/demo/weather.py @fabaff
|
||||
|
10
Dockerfile
10
Dockerfile
@ -5,6 +5,8 @@ FROM ${BUILD_FROM}
|
||||
ENV \
|
||||
S6_SERVICES_GRACETIME=220000
|
||||
|
||||
ARG QEMU_CPU
|
||||
|
||||
WORKDIR /usr/src
|
||||
|
||||
## Setup Home Assistant Core dependencies
|
||||
@ -19,7 +21,7 @@ RUN \
|
||||
--use-deprecated=legacy-resolver \
|
||||
-r homeassistant/requirements.txt
|
||||
|
||||
COPY requirements_all.txt home_assistant_frontend-* homeassistant/
|
||||
COPY requirements_all.txt home_assistant_frontend-* home_assistant_intents-* homeassistant/
|
||||
RUN \
|
||||
if ls homeassistant/home_assistant_frontend*.whl 1> /dev/null 2>&1; then \
|
||||
pip3 install \
|
||||
@ -27,6 +29,12 @@ RUN \
|
||||
--no-index \
|
||||
homeassistant/home_assistant_frontend-*.whl; \
|
||||
fi \
|
||||
&& if ls homeassistant/home_assistant_intents*.whl 1> /dev/null 2>&1; then \
|
||||
pip3 install \
|
||||
--no-cache-dir \
|
||||
--no-index \
|
||||
homeassistant/home_assistant_intents-*.whl; \
|
||||
fi \
|
||||
&& \
|
||||
LD_PRELOAD="/usr/local/lib/libjemalloc.so.2" \
|
||||
MALLOC_CONF="background_thread:true,metadata_thp:auto,dirty_decay_ms:20000,muzzy_decay_ms:20000" \
|
||||
|
@ -1,4 +1,4 @@
|
||||
FROM mcr.microsoft.com/vscode/devcontainers/python:0-3.9
|
||||
FROM mcr.microsoft.com/vscode/devcontainers/python:0-3.10
|
||||
|
||||
SHELL ["/bin/bash", "-o", "pipefail", "-c"]
|
||||
|
||||
|
22
codecov.yml
22
codecov.yml
@ -6,19 +6,37 @@ coverage:
|
||||
default:
|
||||
target: 90
|
||||
threshold: 0.09
|
||||
config-flows:
|
||||
required:
|
||||
target: auto
|
||||
threshold: 1
|
||||
paths:
|
||||
- homeassistant/components/*/config_flow.py
|
||||
- homeassistant/components/*/device_action.py
|
||||
- homeassistant/components/*/device_condition.py
|
||||
- homeassistant/components/*/device_trigger.py
|
||||
- homeassistant/components/*/diagnostics.py
|
||||
- homeassistant/components/*/group.py
|
||||
- homeassistant/components/*/intent.py
|
||||
- homeassistant/components/*/logbook.py
|
||||
- homeassistant/components/*/media_source.py
|
||||
- homeassistant/components/*/scene.py
|
||||
patch:
|
||||
default:
|
||||
target: auto
|
||||
config-flows:
|
||||
required:
|
||||
target: 100
|
||||
threshold: 0
|
||||
paths:
|
||||
- homeassistant/components/*/config_flow.py
|
||||
- homeassistant/components/*/device_action.py
|
||||
- homeassistant/components/*/device_condition.py
|
||||
- homeassistant/components/*/device_trigger.py
|
||||
- homeassistant/components/*/diagnostics.py
|
||||
- homeassistant/components/*/group.py
|
||||
- homeassistant/components/*/intent.py
|
||||
- homeassistant/components/*/logbook.py
|
||||
- homeassistant/components/*/media_source.py
|
||||
- homeassistant/components/*/scene.py
|
||||
comment: false
|
||||
|
||||
# To make partial tests possible,
|
||||
|
@ -1,6 +1,5 @@
|
||||
"""
|
||||
Sphinx extension to add ReadTheDocs-style "Edit on GitHub" links to the
|
||||
sidebar.
|
||||
Sphinx extension for ReadTheDocs-style "Edit on GitHub" links on the sidebar.
|
||||
|
||||
Loosely based on https://github.com/astropy/astropy/pull/347
|
||||
"""
|
||||
@ -12,6 +11,7 @@ __licence__ = "BSD (3 clause)"
|
||||
|
||||
|
||||
def get_github_url(app, view, path):
|
||||
"""Build the GitHub URL."""
|
||||
return (
|
||||
f"https://github.com/{app.config.edit_on_github_project}/"
|
||||
f"{view}/{app.config.edit_on_github_branch}/"
|
||||
@ -20,6 +20,7 @@ def get_github_url(app, view, path):
|
||||
|
||||
|
||||
def html_page_context(app, pagename, templatename, context, doctree):
|
||||
"""Build the HTML page."""
|
||||
if templatename != "page.html":
|
||||
return
|
||||
|
||||
@ -38,6 +39,7 @@ def html_page_context(app, pagename, templatename, context, doctree):
|
||||
|
||||
|
||||
def setup(app):
|
||||
"""Set up the app."""
|
||||
app.add_config_value("edit_on_github_project", "", True)
|
||||
app.add_config_value("edit_on_github_branch", "master", True)
|
||||
app.add_config_value("edit_on_github_src_path", "", True) # 'eg' "docs/"
|
||||
|
@ -1,21 +1,20 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Home-Assistant documentation build configuration file, created by
|
||||
# sphinx-quickstart on Sun Aug 28 13:13:10 2016.
|
||||
#
|
||||
# This file is execfile()d with the current directory set to its
|
||||
# containing dir.
|
||||
#
|
||||
# Note that not all possible configuration values are present in this
|
||||
# autogenerated file.
|
||||
#
|
||||
# All configuration values have a default; values that are commented out
|
||||
# serve to show the default.
|
||||
"""Home Assistant documentation build configuration file.
|
||||
|
||||
This file is execfile()d with the current directory set to its
|
||||
containing dir.
|
||||
|
||||
Note that not all possible configuration values are present in this
|
||||
autogenerated file.
|
||||
|
||||
All configuration values have a default; values that are commented out
|
||||
serve to show the default.
|
||||
|
||||
If extensions (or modules to document with autodoc) are in another directory,
|
||||
add these directories to sys.path here. If the directory is relative to the
|
||||
documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
"""
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#
|
||||
import inspect
|
||||
import os
|
||||
import sys
|
||||
@ -25,7 +24,7 @@ from homeassistant.const import __short_version__, __version__
|
||||
PROJECT_NAME = "Home Assistant"
|
||||
PROJECT_PACKAGE_NAME = "homeassistant"
|
||||
PROJECT_AUTHOR = "The Home Assistant Authors"
|
||||
PROJECT_COPYRIGHT = f" 2013-2020, {PROJECT_AUTHOR}"
|
||||
PROJECT_COPYRIGHT = PROJECT_AUTHOR
|
||||
PROJECT_LONG_DESCRIPTION = (
|
||||
"Home Assistant is an open-source "
|
||||
"home automation platform running on Python 3. "
|
||||
@ -110,17 +109,17 @@ def linkcode_resolve(domain, info):
|
||||
for part in fullname.split("."):
|
||||
try:
|
||||
obj = getattr(obj, part)
|
||||
except:
|
||||
except Exception: # pylint: disable=broad-except
|
||||
return None
|
||||
try:
|
||||
fn = inspect.getsourcefile(obj)
|
||||
except:
|
||||
except Exception: # pylint: disable=broad-except
|
||||
fn = None
|
||||
if not fn:
|
||||
return None
|
||||
try:
|
||||
source, lineno = inspect.findsource(obj)
|
||||
except:
|
||||
except Exception: # pylint: disable=broad-except
|
||||
lineno = None
|
||||
if lineno:
|
||||
linespec = "#L%d" % (lineno + 1)
|
||||
|
@ -15,7 +15,10 @@ FAULT_LOG_FILENAME = "home-assistant.log.fault"
|
||||
def validate_os() -> None:
|
||||
"""Validate that Home Assistant is running in a supported operating system."""
|
||||
if not sys.platform.startswith(("darwin", "linux")):
|
||||
print("Home Assistant only supports Linux, OSX and Windows using WSL")
|
||||
print(
|
||||
"Home Assistant only supports Linux, OSX and Windows using WSL",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
@ -24,14 +27,15 @@ def validate_python() -> None:
|
||||
if sys.version_info[:3] < REQUIRED_PYTHON_VER:
|
||||
print(
|
||||
"Home Assistant requires at least Python "
|
||||
f"{REQUIRED_PYTHON_VER[0]}.{REQUIRED_PYTHON_VER[1]}.{REQUIRED_PYTHON_VER[2]}"
|
||||
f"{REQUIRED_PYTHON_VER[0]}.{REQUIRED_PYTHON_VER[1]}.{REQUIRED_PYTHON_VER[2]}",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def ensure_config_path(config_dir: str) -> None:
|
||||
"""Validate the configuration directory."""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
# pylint: disable-next=import-outside-toplevel
|
||||
from . import config as config_util
|
||||
|
||||
lib_dir = os.path.join(config_dir, "deps")
|
||||
@ -39,18 +43,23 @@ def ensure_config_path(config_dir: str) -> None:
|
||||
# Test if configuration directory exists
|
||||
if not os.path.isdir(config_dir):
|
||||
if config_dir != config_util.get_default_config_dir():
|
||||
if os.path.exists(config_dir):
|
||||
reason = "is not a directory"
|
||||
else:
|
||||
reason = "does not exist"
|
||||
print(
|
||||
f"Fatal Error: Specified configuration directory {config_dir} "
|
||||
"does not exist"
|
||||
f"Fatal Error: Specified configuration directory {config_dir} {reason}",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
os.mkdir(config_dir)
|
||||
except OSError:
|
||||
except OSError as ex:
|
||||
print(
|
||||
"Fatal Error: Unable to create default configuration "
|
||||
f"directory {config_dir}"
|
||||
f"directory {config_dir}: {ex}",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
@ -58,14 +67,17 @@ def ensure_config_path(config_dir: str) -> None:
|
||||
if not os.path.isdir(lib_dir):
|
||||
try:
|
||||
os.mkdir(lib_dir)
|
||||
except OSError:
|
||||
print(f"Fatal Error: Unable to create library directory {lib_dir}")
|
||||
except OSError as ex:
|
||||
print(
|
||||
f"Fatal Error: Unable to create library directory {lib_dir}: {ex}",
|
||||
file=sys.stderr,
|
||||
)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def get_arguments() -> argparse.Namespace:
|
||||
"""Get parsed passed in arguments."""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
# pylint: disable-next=import-outside-toplevel
|
||||
from . import config as config_util
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
@ -172,7 +184,7 @@ def main() -> int:
|
||||
validate_os()
|
||||
|
||||
if args.script is not None:
|
||||
# pylint: disable=import-outside-toplevel
|
||||
# pylint: disable-next=import-outside-toplevel
|
||||
from . import scripts
|
||||
|
||||
return scripts.run(args.script)
|
||||
@ -180,7 +192,7 @@ def main() -> int:
|
||||
config_dir = os.path.abspath(os.path.join(os.getcwd(), args.config))
|
||||
ensure_config_path(config_dir)
|
||||
|
||||
# pylint: disable=import-outside-toplevel
|
||||
# pylint: disable-next=import-outside-toplevel
|
||||
from . import runner
|
||||
|
||||
runtime_conf = runner.RuntimeConfig(
|
||||
|
@ -5,7 +5,7 @@ import asyncio
|
||||
from collections import OrderedDict
|
||||
from collections.abc import Mapping
|
||||
from datetime import timedelta
|
||||
from typing import Any, Optional, cast
|
||||
from typing import Any, cast
|
||||
|
||||
import jwt
|
||||
|
||||
@ -24,7 +24,7 @@ EVENT_USER_UPDATED = "user_updated"
|
||||
EVENT_USER_REMOVED = "user_removed"
|
||||
|
||||
_MfaModuleDict = dict[str, MultiFactorAuthModule]
|
||||
_ProviderKey = tuple[str, Optional[str]]
|
||||
_ProviderKey = tuple[str, str | None]
|
||||
_ProviderDict = dict[_ProviderKey, AuthProvider]
|
||||
|
||||
|
||||
|
@ -555,7 +555,9 @@ class AuthStore:
|
||||
"client_icon": refresh_token.client_icon,
|
||||
"token_type": refresh_token.token_type,
|
||||
"created_at": refresh_token.created_at.isoformat(),
|
||||
"access_token_expiration": refresh_token.access_token_expiration.total_seconds(),
|
||||
"access_token_expiration": (
|
||||
refresh_token.access_token_expiration.total_seconds()
|
||||
),
|
||||
"token": refresh_token.token,
|
||||
"jwt_key": refresh_token.jwt_key,
|
||||
"last_used_at": refresh_token.last_used_at.isoformat()
|
||||
|
@ -1,29 +1,28 @@
|
||||
"""Common code for permissions."""
|
||||
from collections.abc import Mapping
|
||||
from typing import Union
|
||||
|
||||
# MyPy doesn't support recursion yet. So writing it out as far as we need.
|
||||
|
||||
ValueType = Union[
|
||||
ValueType = (
|
||||
# Example: entities.all = { read: true, control: true }
|
||||
Mapping[str, bool],
|
||||
bool,
|
||||
None,
|
||||
]
|
||||
Mapping[str, bool]
|
||||
| bool
|
||||
| None
|
||||
)
|
||||
|
||||
# Example: entities.domains = { light: … }
|
||||
SubCategoryDict = Mapping[str, ValueType]
|
||||
|
||||
SubCategoryType = Union[SubCategoryDict, bool, None]
|
||||
SubCategoryType = SubCategoryDict | bool | None
|
||||
|
||||
CategoryType = Union[
|
||||
CategoryType = (
|
||||
# Example: entities.domains
|
||||
Mapping[str, SubCategoryType],
|
||||
Mapping[str, SubCategoryType]
|
||||
# Example: entities.all
|
||||
Mapping[str, ValueType],
|
||||
bool,
|
||||
None,
|
||||
]
|
||||
| Mapping[str, ValueType]
|
||||
| bool
|
||||
| None
|
||||
)
|
||||
|
||||
# Example: { entities: … }
|
||||
PolicyType = Mapping[str, CategoryType]
|
||||
|
@ -3,13 +3,13 @@ from __future__ import annotations
|
||||
|
||||
from collections.abc import Callable
|
||||
from functools import wraps
|
||||
from typing import Optional, cast
|
||||
from typing import cast
|
||||
|
||||
from .const import SUBCAT_ALL
|
||||
from .models import PermissionLookup
|
||||
from .types import CategoryType, SubCategoryDict, ValueType
|
||||
|
||||
LookupFunc = Callable[[PermissionLookup, SubCategoryDict, str], Optional[ValueType]]
|
||||
LookupFunc = Callable[[PermissionLookup, SubCategoryDict, str], ValueType | None]
|
||||
SubCatLookupType = dict[str, LookupFunc]
|
||||
|
||||
|
||||
|
@ -14,7 +14,7 @@ from ipaddress import (
|
||||
ip_address,
|
||||
ip_network,
|
||||
)
|
||||
from typing import Any, Union, cast
|
||||
from typing import Any, cast
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
@ -27,8 +27,8 @@ from . import AUTH_PROVIDER_SCHEMA, AUTH_PROVIDERS, AuthProvider, LoginFlow
|
||||
from .. import InvalidAuthError
|
||||
from ..models import Credentials, RefreshToken, UserMeta
|
||||
|
||||
IPAddress = Union[IPv4Address, IPv6Address]
|
||||
IPNetwork = Union[IPv4Network, IPv6Network]
|
||||
IPAddress = IPv4Address | IPv6Address
|
||||
IPNetwork = IPv4Network | IPv6Network
|
||||
|
||||
CONF_TRUSTED_NETWORKS = "trusted_networks"
|
||||
CONF_TRUSTED_USERS = "trusted_users"
|
||||
|
@ -8,7 +8,9 @@ from .util.async_ import protect_loop
|
||||
def enable() -> None:
|
||||
"""Enable the detection of blocking calls in the event loop."""
|
||||
# Prevent urllib3 and requests doing I/O in event loop
|
||||
HTTPConnection.putrequest = protect_loop(HTTPConnection.putrequest) # type: ignore[assignment]
|
||||
HTTPConnection.putrequest = protect_loop( # type: ignore[assignment]
|
||||
HTTPConnection.putrequest
|
||||
)
|
||||
|
||||
# Prevent sleeping in event loop. Non-strict since 2022.02
|
||||
time.sleep = protect_loop(time.sleep, strict=False)
|
||||
|
@ -346,7 +346,7 @@ def async_enable_logging(
|
||||
|
||||
if not log_no_color:
|
||||
try:
|
||||
# pylint: disable=import-outside-toplevel
|
||||
# pylint: disable-next=import-outside-toplevel
|
||||
from colorlog import ColoredFormatter
|
||||
|
||||
# basicConfig must be called after importing colorlog in order to
|
||||
@ -385,7 +385,11 @@ def async_enable_logging(
|
||||
)
|
||||
threading.excepthook = lambda args: logging.getLogger(None).exception(
|
||||
"Uncaught thread exception",
|
||||
exc_info=(args.exc_type, args.exc_value, args.exc_traceback), # type: ignore[arg-type]
|
||||
exc_info=( # type: ignore[arg-type]
|
||||
args.exc_type,
|
||||
args.exc_value,
|
||||
args.exc_traceback,
|
||||
),
|
||||
)
|
||||
|
||||
# Log errors to a file if we have write access to file or config dir
|
||||
@ -403,7 +407,10 @@ def async_enable_logging(
|
||||
not err_path_exists and os.access(err_dir, os.W_OK)
|
||||
):
|
||||
|
||||
err_handler: logging.handlers.RotatingFileHandler | logging.handlers.TimedRotatingFileHandler
|
||||
err_handler: (
|
||||
logging.handlers.RotatingFileHandler
|
||||
| logging.handlers.TimedRotatingFileHandler
|
||||
)
|
||||
if log_rotate_days:
|
||||
err_handler = logging.handlers.TimedRotatingFileHandler(
|
||||
err_log_path, when="midnight", backupCount=log_rotate_days
|
||||
@ -462,7 +469,10 @@ def _get_domains(hass: core.HomeAssistant, config: dict[str, Any]) -> set[str]:
|
||||
|
||||
|
||||
async def _async_watch_pending_setups(hass: core.HomeAssistant) -> None:
|
||||
"""Periodic log of setups that are pending for longer than LOG_SLOW_STARTUP_INTERVAL."""
|
||||
"""Periodic log of setups that are pending.
|
||||
|
||||
Pending for longer than LOG_SLOW_STARTUP_INTERVAL.
|
||||
"""
|
||||
loop_count = 0
|
||||
setup_started: dict[str, datetime] = hass.data[DATA_SETUP_STARTED]
|
||||
previous_was_empty = True
|
||||
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"domain": "amazon",
|
||||
"name": "Amazon",
|
||||
"integrations": ["alexa", "amazon_polly", "aws", "route53"]
|
||||
"integrations": ["alexa", "amazon_polly", "aws", "fire_tv", "route53"]
|
||||
}
|
||||
|
6
homeassistant/brands/eufy.json
Normal file
6
homeassistant/brands/eufy.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"domain": "eufy",
|
||||
"name": "eufy",
|
||||
"integrations": ["eufy", "eufylife_ble"],
|
||||
"iot_standards": []
|
||||
}
|
@ -6,6 +6,7 @@
|
||||
"google_assistant_sdk",
|
||||
"google_cloud",
|
||||
"google_domains",
|
||||
"google_mail",
|
||||
"google_maps",
|
||||
"google_pubsub",
|
||||
"google_sheets",
|
||||
|
@ -3,10 +3,14 @@ from __future__ import annotations
|
||||
|
||||
from functools import partial
|
||||
|
||||
from abodepy import Abode, AbodeAutomation as AbodeAuto
|
||||
from abodepy.devices import AbodeDevice as AbodeDev
|
||||
from abodepy.exceptions import AbodeAuthenticationException, AbodeException
|
||||
import abodepy.helpers.timeline as TIMELINE
|
||||
from jaraco.abode.automation import Automation as AbodeAuto
|
||||
from jaraco.abode.client import Client as Abode
|
||||
from jaraco.abode.devices.base import Device as AbodeDev
|
||||
from jaraco.abode.exceptions import (
|
||||
AuthenticationException as AbodeAuthenticationException,
|
||||
Exception as AbodeException,
|
||||
)
|
||||
from jaraco.abode.helpers.timeline import Groups as GROUPS
|
||||
from requests.exceptions import ConnectTimeout, HTTPError
|
||||
import voluptuous as vol
|
||||
|
||||
@ -26,7 +30,7 @@ from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
|
||||
from homeassistant.helpers import config_validation as cv, entity
|
||||
from homeassistant.helpers.dispatcher import dispatcher_send
|
||||
|
||||
from .const import ATTRIBUTION, CONF_POLLING, DEFAULT_CACHEDB, DOMAIN, LOGGER
|
||||
from .const import ATTRIBUTION, CONF_POLLING, DOMAIN, LOGGER
|
||||
|
||||
SERVICE_SETTINGS = "change_setting"
|
||||
SERVICE_CAPTURE_IMAGE = "capture_image"
|
||||
@ -82,7 +86,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
username = entry.data[CONF_USERNAME]
|
||||
password = entry.data[CONF_PASSWORD]
|
||||
polling = entry.data[CONF_POLLING]
|
||||
cache = hass.config.path(DEFAULT_CACHEDB)
|
||||
|
||||
# For previous config entries where unique_id is None
|
||||
if entry.unique_id is None:
|
||||
@ -92,7 +95,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
|
||||
try:
|
||||
abode = await hass.async_add_executor_job(
|
||||
Abode, username, password, True, True, True, cache
|
||||
Abode, username, password, True, True, True
|
||||
)
|
||||
|
||||
except AbodeAuthenticationException as ex:
|
||||
@ -225,17 +228,17 @@ def setup_abode_events(hass: HomeAssistant) -> None:
|
||||
hass.bus.fire(event, data)
|
||||
|
||||
events = [
|
||||
TIMELINE.ALARM_GROUP,
|
||||
TIMELINE.ALARM_END_GROUP,
|
||||
TIMELINE.PANEL_FAULT_GROUP,
|
||||
TIMELINE.PANEL_RESTORE_GROUP,
|
||||
TIMELINE.AUTOMATION_GROUP,
|
||||
TIMELINE.DISARM_GROUP,
|
||||
TIMELINE.ARM_GROUP,
|
||||
TIMELINE.ARM_FAULT_GROUP,
|
||||
TIMELINE.TEST_GROUP,
|
||||
TIMELINE.CAPTURE_GROUP,
|
||||
TIMELINE.DEVICE_GROUP,
|
||||
GROUPS.ALARM,
|
||||
GROUPS.ALARM_END,
|
||||
GROUPS.PANEL_FAULT,
|
||||
GROUPS.PANEL_RESTORE,
|
||||
GROUPS.AUTOMATION,
|
||||
GROUPS.DISARM,
|
||||
GROUPS.ARM,
|
||||
GROUPS.ARM_FAULT,
|
||||
GROUPS.TEST,
|
||||
GROUPS.CAPTURE,
|
||||
GROUPS.DEVICE,
|
||||
]
|
||||
|
||||
for event in events:
|
||||
|
@ -1,7 +1,7 @@
|
||||
"""Support for Abode Security System alarm control panels."""
|
||||
from __future__ import annotations
|
||||
|
||||
from abodepy.devices.alarm import AbodeAlarm as AbodeAl
|
||||
from jaraco.abode.devices.alarm import Alarm as AbodeAl
|
||||
|
||||
import homeassistant.components.alarm_control_panel as alarm
|
||||
from homeassistant.components.alarm_control_panel import AlarmControlPanelEntityFeature
|
||||
|
@ -4,8 +4,8 @@ from __future__ import annotations
|
||||
from contextlib import suppress
|
||||
from typing import cast
|
||||
|
||||
from abodepy.devices.binary_sensor import AbodeBinarySensor as ABBinarySensor
|
||||
import abodepy.helpers.constants as CONST
|
||||
from jaraco.abode.devices.sensor import BinarySensor as ABBinarySensor
|
||||
from jaraco.abode.helpers import constants as CONST
|
||||
|
||||
from homeassistant.components.binary_sensor import (
|
||||
BinarySensorDeviceClass,
|
||||
|
@ -4,9 +4,9 @@ from __future__ import annotations
|
||||
from datetime import timedelta
|
||||
from typing import Any, cast
|
||||
|
||||
from abodepy.devices import CONST, AbodeDevice as AbodeDev
|
||||
from abodepy.devices.camera import AbodeCamera as AbodeCam
|
||||
import abodepy.helpers.timeline as TIMELINE
|
||||
from jaraco.abode.devices.base import Device as AbodeDev
|
||||
from jaraco.abode.devices.camera import Camera as AbodeCam
|
||||
from jaraco.abode.helpers import constants as CONST, timeline as TIMELINE
|
||||
import requests
|
||||
from requests.models import Response
|
||||
|
||||
@ -30,7 +30,7 @@ async def async_setup_entry(
|
||||
data: AbodeSystem = hass.data[DOMAIN]
|
||||
|
||||
async_add_entities(
|
||||
AbodeCamera(data, device, TIMELINE.CAPTURE_IMAGE)
|
||||
AbodeCamera(data, device, TIMELINE.CAPTURE_IMAGE) # pylint: disable=no-member
|
||||
for device in data.abode.get_devices(generic_type=CONST.TYPE_CAMERA)
|
||||
)
|
||||
|
||||
|
@ -5,9 +5,12 @@ from collections.abc import Mapping
|
||||
from http import HTTPStatus
|
||||
from typing import Any, cast
|
||||
|
||||
from abodepy import Abode
|
||||
from abodepy.exceptions import AbodeAuthenticationException, AbodeException
|
||||
from abodepy.helpers.errors import MFA_CODE_REQUIRED
|
||||
from jaraco.abode.client import Client as Abode
|
||||
from jaraco.abode.exceptions import (
|
||||
AuthenticationException as AbodeAuthenticationException,
|
||||
Exception as AbodeException,
|
||||
)
|
||||
from jaraco.abode.helpers.errors import MFA_CODE_REQUIRED
|
||||
from requests.exceptions import ConnectTimeout, HTTPError
|
||||
import voluptuous as vol
|
||||
|
||||
@ -15,7 +18,7 @@ from homeassistant import config_entries
|
||||
from homeassistant.const import CONF_PASSWORD, CONF_USERNAME
|
||||
from homeassistant.data_entry_flow import FlowResult
|
||||
|
||||
from .const import CONF_POLLING, DEFAULT_CACHEDB, DOMAIN, LOGGER
|
||||
from .const import CONF_POLLING, DOMAIN, LOGGER
|
||||
|
||||
CONF_MFA = "mfa_code"
|
||||
|
||||
@ -35,7 +38,6 @@ class AbodeFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
vol.Required(CONF_MFA): str,
|
||||
}
|
||||
|
||||
self._cache: str | None = None
|
||||
self._mfa_code: str | None = None
|
||||
self._password: str | None = None
|
||||
self._polling: bool = False
|
||||
@ -43,12 +45,11 @@ class AbodeFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
|
||||
async def _async_abode_login(self, step_id: str) -> FlowResult:
|
||||
"""Handle login with Abode."""
|
||||
self._cache = self.hass.config.path(DEFAULT_CACHEDB)
|
||||
errors = {}
|
||||
|
||||
try:
|
||||
await self.hass.async_add_executor_job(
|
||||
Abode, self._username, self._password, True, False, False, self._cache
|
||||
Abode, self._username, self._password, True, False, False
|
||||
)
|
||||
|
||||
except AbodeException as ex:
|
||||
@ -77,12 +78,7 @@ class AbodeFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
"""Handle multi-factor authentication (MFA) login with Abode."""
|
||||
try:
|
||||
# Create instance to access login method for passing MFA code
|
||||
abode = Abode(
|
||||
auto_login=False,
|
||||
get_devices=False,
|
||||
get_automations=False,
|
||||
cache_path=self._cache,
|
||||
)
|
||||
abode = Abode(auto_login=False, get_devices=False, get_automations=False)
|
||||
await self.hass.async_add_executor_job(
|
||||
abode.login, self._username, self._password, self._mfa_code
|
||||
)
|
||||
|
@ -6,5 +6,4 @@ LOGGER = logging.getLogger(__package__)
|
||||
DOMAIN = "abode"
|
||||
ATTRIBUTION = "Data provided by goabode.com"
|
||||
|
||||
DEFAULT_CACHEDB = "abodepy_cache.pickle"
|
||||
CONF_POLLING = "polling"
|
||||
|
@ -1,8 +1,8 @@
|
||||
"""Support for Abode Security System covers."""
|
||||
from typing import Any
|
||||
|
||||
from abodepy.devices.cover import AbodeCover as AbodeCV
|
||||
import abodepy.helpers.constants as CONST
|
||||
from jaraco.abode.devices.cover import Cover as AbodeCV
|
||||
from jaraco.abode.helpers import constants as CONST
|
||||
|
||||
from homeassistant.components.cover import CoverEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
|
@ -4,8 +4,8 @@ from __future__ import annotations
|
||||
from math import ceil
|
||||
from typing import Any
|
||||
|
||||
from abodepy.devices.light import AbodeLight as AbodeLT
|
||||
import abodepy.helpers.constants as CONST
|
||||
from jaraco.abode.devices.light import Light as AbodeLT
|
||||
from jaraco.abode.helpers import constants as CONST
|
||||
|
||||
from homeassistant.components.light import (
|
||||
ATTR_BRIGHTNESS,
|
||||
|
@ -1,8 +1,8 @@
|
||||
"""Support for the Abode Security System locks."""
|
||||
from typing import Any
|
||||
|
||||
from abodepy.devices.lock import AbodeLock as AbodeLK
|
||||
import abodepy.helpers.constants as CONST
|
||||
from jaraco.abode.devices.lock import Lock as AbodeLK
|
||||
from jaraco.abode.helpers import constants as CONST
|
||||
|
||||
from homeassistant.components.lock import LockEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
|
@ -3,11 +3,11 @@
|
||||
"name": "Abode",
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/abode",
|
||||
"requirements": ["abodepy==1.2.0"],
|
||||
"requirements": ["jaraco.abode==3.2.1"],
|
||||
"codeowners": ["@shred86"],
|
||||
"homekit": {
|
||||
"models": ["Abode", "Iota"]
|
||||
},
|
||||
"iot_class": "cloud_push",
|
||||
"loggers": ["abodepy", "lomond"]
|
||||
"loggers": ["jaraco.abode", "lomond"]
|
||||
}
|
||||
|
@ -3,7 +3,8 @@ from __future__ import annotations
|
||||
|
||||
from typing import cast
|
||||
|
||||
from abodepy.devices.sensor import CONST, AbodeSensor as AbodeSense
|
||||
from jaraco.abode.devices.sensor import Sensor as AbodeSense
|
||||
from jaraco.abode.helpers import constants as CONST
|
||||
|
||||
from homeassistant.components.sensor import (
|
||||
SensorDeviceClass,
|
||||
|
@ -3,7 +3,8 @@ from __future__ import annotations
|
||||
|
||||
from typing import Any, cast
|
||||
|
||||
from abodepy.devices.switch import CONST, AbodeSwitch as AbodeSW
|
||||
from jaraco.abode.devices.switch import Switch as AbodeSW
|
||||
from jaraco.abode.helpers import constants as CONST
|
||||
|
||||
from homeassistant.components.switch import SwitchEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
|
12
homeassistant/components/abode/translations/lt.json
Normal file
12
homeassistant/components/abode/translations/lt.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"config": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Slapta\u017eodis",
|
||||
"username": "El. pa\u0161tas"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
"""Diagnostics support for AccuWeather."""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.components.diagnostics import async_redact_data
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE
|
||||
@ -14,7 +16,7 @@ TO_REDACT = {CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE}
|
||||
|
||||
async def async_get_config_entry_diagnostics(
|
||||
hass: HomeAssistant, config_entry: ConfigEntry
|
||||
) -> dict:
|
||||
) -> dict[str, Any]:
|
||||
"""Return diagnostics for a config entry."""
|
||||
coordinator: AccuWeatherDataUpdateCoordinator = hass.data[DOMAIN][
|
||||
config_entry.entry_id
|
||||
|
@ -2,7 +2,7 @@
|
||||
"domain": "accuweather",
|
||||
"name": "AccuWeather",
|
||||
"documentation": "https://www.home-assistant.io/integrations/accuweather/",
|
||||
"requirements": ["accuweather==0.4.0"],
|
||||
"requirements": ["accuweather==0.5.0"],
|
||||
"codeowners": ["@bieniu"],
|
||||
"config_flow": true,
|
||||
"quality_scale": "platinum",
|
||||
|
@ -17,10 +17,10 @@ from homeassistant.const import (
|
||||
PERCENTAGE,
|
||||
UV_INDEX,
|
||||
UnitOfLength,
|
||||
UnitOfPrecipitationDepth,
|
||||
UnitOfSpeed,
|
||||
UnitOfTemperature,
|
||||
UnitOfTime,
|
||||
UnitOfVolumetricFlux,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
@ -290,11 +290,11 @@ SENSOR_TYPES: tuple[AccuWeatherSensorDescription, ...] = (
|
||||
),
|
||||
AccuWeatherSensorDescription(
|
||||
key="Precipitation",
|
||||
device_class=SensorDeviceClass.PRECIPITATION,
|
||||
device_class=SensorDeviceClass.PRECIPITATION_INTENSITY,
|
||||
name="Precipitation",
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
metric_unit=UnitOfPrecipitationDepth.MILLIMETERS,
|
||||
us_customary_unit=UnitOfPrecipitationDepth.INCHES,
|
||||
metric_unit=UnitOfVolumetricFlux.MILLIMETERS_PER_HOUR,
|
||||
us_customary_unit=UnitOfVolumetricFlux.INCHES_PER_HOUR,
|
||||
value_fn=lambda data, unit: cast(float, data[unit][ATTR_VALUE]),
|
||||
attr_fn=lambda data: {"type": data["PrecipitationType"]},
|
||||
),
|
||||
@ -452,7 +452,7 @@ def _get_sensor_data(
|
||||
return sensors[ATTR_FORECAST][forecast_day][kind]
|
||||
|
||||
if kind == "Precipitation":
|
||||
return sensors["PrecipitationSummary"][kind]
|
||||
return sensors["PrecipitationSummary"]["PastHour"]
|
||||
|
||||
return sensors[kind]
|
||||
|
||||
|
@ -22,6 +22,27 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"entity": {
|
||||
"sensor": {
|
||||
"pressure_tendency": {
|
||||
"state": {
|
||||
"falling": "D\u00fc\u015f\u00fcyor",
|
||||
"rising": "Y\u00fckseliyor",
|
||||
"steady": "Sabit"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"init": {
|
||||
"data": {
|
||||
"forecast": "Hava Durumu tahmini"
|
||||
},
|
||||
"description": "AccuWeather API anahtar\u0131n\u0131n \u00fccretsiz s\u00fcr\u00fcm\u00fcn\u00fcn s\u0131n\u0131rlamalar\u0131 nedeniyle, hava tahminini etkinle\u015ftirdi\u011finizde, veri g\u00fcncellemeleri her 40 dakikada bir yerine 80 dakikada bir ger\u00e7ekle\u015ftirilir."
|
||||
}
|
||||
}
|
||||
},
|
||||
"system_health": {
|
||||
"info": {
|
||||
"can_reach_server": "AccuWeather sunucusuna ula\u015f\u0131n",
|
||||
|
@ -1,5 +1,8 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Ier\u012bce jau pievienota Home Assistant."
|
||||
},
|
||||
"step": {
|
||||
"cloud": {
|
||||
"data": {
|
||||
|
15
homeassistant/components/adax/translations/uk.json
Normal file
15
homeassistant/components/adax/translations/uk.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"invalid_auth": "\u041d\u0435\u0434\u0456\u0439\u0441\u043d\u0430 \u0430\u0432\u0442\u0435\u043d\u0442\u0438\u0444\u0456\u043a\u0430\u0446\u0456\u044f"
|
||||
},
|
||||
"step": {
|
||||
"cloud": {
|
||||
"data": {
|
||||
"account_id": "ID \u041e\u0431\u043b\u0456\u043a\u043e\u0432\u043e\u0433\u043e \u0437\u0430\u043f\u0438\u0441\u0443",
|
||||
"password": "\u041f\u0430\u0440\u043e\u043b\u044c"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -58,7 +58,12 @@ class AdGuardHomeEntity(Entity):
|
||||
return DeviceInfo(
|
||||
entry_type=DeviceEntryType.SERVICE,
|
||||
identifiers={
|
||||
(DOMAIN, self.adguard.host, self.adguard.port, self.adguard.base_path) # type: ignore[arg-type]
|
||||
( # type: ignore[arg-type]
|
||||
DOMAIN,
|
||||
self.adguard.host,
|
||||
self.adguard.port,
|
||||
self.adguard.base_path,
|
||||
)
|
||||
},
|
||||
manufacturer="AdGuard Team",
|
||||
name="AdGuard Home",
|
||||
|
11
homeassistant/components/adguard/translations/lt.json
Normal file
11
homeassistant/components/adguard/translations/lt.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"config": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Slapta\u017eodis"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Ier\u012bce jau pievienota Home Assistant."
|
||||
}
|
||||
}
|
||||
}
|
@ -14,7 +14,7 @@
|
||||
"longitude": "\u0393\u03b5\u03c9\u03b3\u03c1\u03b1\u03c6\u03b9\u03ba\u03cc \u03bc\u03ae\u03ba\u03bf\u03c2",
|
||||
"name": "\u038c\u03bd\u03bf\u03bc\u03b1 \u03c4\u03b7\u03c2 \u03b5\u03bd\u03c3\u03c9\u03bc\u03ac\u03c4\u03c9\u03c3\u03b7\u03c2"
|
||||
},
|
||||
"description": "\u03a1\u03cd\u03b8\u03bc\u03b9\u03c3\u03b7 \u03c4\u03b7\u03c2 \u03b5\u03bd\u03c3\u03c9\u03bc\u03ac\u03c4\u03c9\u03c3\u03b7\u03c2 \u03c4\u03bf\u03c5 AEMET OpenData. \u0393\u03b9\u03b1 \u03bd\u03b1 \u03b4\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03ae\u03c3\u03b5\u03c4\u03b5 \u03c4\u03bf \u03ba\u03bb\u03b5\u03b9\u03b4\u03af API \u03bc\u03b5\u03c4\u03b1\u03b2\u03b5\u03af\u03c4\u03b5 \u03c3\u03c4\u03b7 \u03b4\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 https://opendata.aemet.es/centrodedescargas/altaUsuario"
|
||||
"description": "\u0393\u03b9\u03b1 \u03bd\u03b1 \u03b4\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03ae\u03c3\u03b5\u03c4\u03b5 \u03ba\u03bb\u03b5\u03b9\u03b4\u03af API, \u03bc\u03b5\u03c4\u03b1\u03b2\u03b5\u03af\u03c4\u03b5 \u03c3\u03c4\u03b7 \u03b4\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 https://opendata.aemet.es/centrodedescargas/altaUsuario"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
7
homeassistant/components/agent_dvr/translations/lv.json
Normal file
7
homeassistant/components/agent_dvr/translations/lv.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Ier\u012bce jau pievienota Home Assistant."
|
||||
}
|
||||
}
|
||||
}
|
@ -150,7 +150,9 @@ class AirlyDataUpdateCoordinator(DataUpdateCoordinator):
|
||||
"""Initialize."""
|
||||
self.latitude = latitude
|
||||
self.longitude = longitude
|
||||
self.airly = Airly(api_key, session)
|
||||
# Currently, Airly only supports Polish and English
|
||||
language = "pl" if hass.config.language == "pl" else "en"
|
||||
self.airly = Airly(api_key, session, language=language)
|
||||
self.use_nearest = use_nearest
|
||||
|
||||
super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=update_interval)
|
||||
|
@ -46,7 +46,7 @@ class AirlyFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
user_input["longitude"],
|
||||
)
|
||||
if not location_point_valid:
|
||||
await test_location(
|
||||
location_nearest_valid = await test_location(
|
||||
websession,
|
||||
user_input["api_key"],
|
||||
user_input["latitude"],
|
||||
@ -60,6 +60,8 @@ class AirlyFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
errors["base"] = "wrong_location"
|
||||
else:
|
||||
if not location_point_valid:
|
||||
if not location_nearest_valid:
|
||||
return self.async_abort(reason="wrong_location")
|
||||
use_nearest = True
|
||||
return self.async_create_entry(
|
||||
title=user_input[CONF_NAME],
|
||||
|
@ -1,6 +1,8 @@
|
||||
"""Diagnostics support for Airly."""
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any
|
||||
|
||||
from homeassistant.components.diagnostics import async_redact_data
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import (
|
||||
@ -19,7 +21,7 @@ TO_REDACT = {CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, CONF_UNIQUE_ID}
|
||||
|
||||
async def async_get_config_entry_diagnostics(
|
||||
hass: HomeAssistant, config_entry: ConfigEntry
|
||||
) -> dict:
|
||||
) -> dict[str, Any]:
|
||||
"""Return diagnostics for a config entry."""
|
||||
coordinator: AirlyDataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id]
|
||||
|
||||
|
@ -16,7 +16,8 @@
|
||||
"invalid_api_key": "[%key:common::config_flow::error::invalid_api_key%]"
|
||||
},
|
||||
"abort": {
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_location%]"
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_location%]",
|
||||
"wrong_location": "No Airly measuring stations in this area."
|
||||
}
|
||||
},
|
||||
"system_health": {
|
||||
|
@ -1,7 +1,8 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "La ubicaci\u00f3 ja est\u00e0 configurada"
|
||||
"already_configured": "La ubicaci\u00f3 ja est\u00e0 configurada",
|
||||
"wrong_location": "No hi ha estacions de mesura Airly en aquesta zona."
|
||||
},
|
||||
"error": {
|
||||
"invalid_api_key": "Clau API inv\u00e0lida",
|
||||
|
@ -1,7 +1,8 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Standort ist bereits konfiguriert"
|
||||
"already_configured": "Standort ist bereits konfiguriert",
|
||||
"wrong_location": "Keine Airly Luftmessstation an diesem Ort"
|
||||
},
|
||||
"error": {
|
||||
"invalid_api_key": "Ung\u00fcltiger API-Schl\u00fcssel",
|
||||
|
@ -1,7 +1,8 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "\u0397 \u03c4\u03bf\u03c0\u03bf\u03b8\u03b5\u03c3\u03af\u03b1 \u03ad\u03c7\u03b5\u03b9 \u03ae\u03b4\u03b7 \u03b4\u03b9\u03b1\u03bc\u03bf\u03c1\u03c6\u03c9\u03b8\u03b5\u03af"
|
||||
"already_configured": "\u0397 \u03c4\u03bf\u03c0\u03bf\u03b8\u03b5\u03c3\u03af\u03b1 \u03ad\u03c7\u03b5\u03b9 \u03ae\u03b4\u03b7 \u03b4\u03b9\u03b1\u03bc\u03bf\u03c1\u03c6\u03c9\u03b8\u03b5\u03af",
|
||||
"wrong_location": "\u0394\u03b5\u03bd \u03c5\u03c0\u03ac\u03c1\u03c7\u03bf\u03c5\u03bd \u03c3\u03c4\u03b1\u03b8\u03bc\u03bf\u03af \u03bc\u03ad\u03c4\u03c1\u03b7\u03c3\u03b7\u03c2 Airly \u03c3\u03b5 \u03b1\u03c5\u03c4\u03ae\u03bd \u03c4\u03b7\u03bd \u03c0\u03b5\u03c1\u03b9\u03bf\u03c7\u03ae."
|
||||
},
|
||||
"error": {
|
||||
"invalid_api_key": "\u0386\u03ba\u03c5\u03c1\u03bf API \u03ba\u03bb\u03b5\u03b9\u03b4\u03af",
|
||||
@ -15,7 +16,7 @@
|
||||
"longitude": "\u0393\u03b5\u03c9\u03b3\u03c1\u03b1\u03c6\u03b9\u03ba\u03cc \u03bc\u03ae\u03ba\u03bf\u03c2",
|
||||
"name": "\u038c\u03bd\u03bf\u03bc\u03b1"
|
||||
},
|
||||
"description": "\u03a1\u03c5\u03b8\u03bc\u03af\u03c3\u03c4\u03b5 \u03c4\u03b7\u03bd \u03b5\u03bd\u03c3\u03c9\u03bc\u03ac\u03c4\u03c9\u03c3\u03b7 \u03c0\u03bf\u03b9\u03cc\u03c4\u03b7\u03c4\u03b1\u03c2 \u03b1\u03ad\u03c1\u03b1 Airly. \u0393\u03b9\u03b1 \u03bd\u03b1 \u03b4\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03ae\u03c3\u03b5\u03c4\u03b5 \u03ba\u03bb\u03b5\u03b9\u03b4\u03af API, \u03bc\u03b5\u03c4\u03b1\u03b2\u03b5\u03af\u03c4\u03b5 \u03c3\u03c4\u03b7 \u03b4\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 https://developer.airly.eu/register"
|
||||
"description": "\u0393\u03b9\u03b1 \u03bd\u03b1 \u03b4\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03ae\u03c3\u03b5\u03c4\u03b5 \u03ba\u03bb\u03b5\u03b9\u03b4\u03af API, \u03bc\u03b5\u03c4\u03b1\u03b2\u03b5\u03af\u03c4\u03b5 \u03c3\u03c4\u03b7 \u03b4\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 https://developer.airly.eu/register"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1,7 +1,8 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Location is already configured"
|
||||
"already_configured": "Location is already configured",
|
||||
"wrong_location": "No Airly measuring stations in this area."
|
||||
},
|
||||
"error": {
|
||||
"invalid_api_key": "Invalid API key",
|
||||
|
@ -1,7 +1,8 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "La ubicaci\u00f3n ya est\u00e1 configurada"
|
||||
"already_configured": "La ubicaci\u00f3n ya est\u00e1 configurada",
|
||||
"wrong_location": "No hay estaciones de medici\u00f3n Airly en esta \u00e1rea."
|
||||
},
|
||||
"error": {
|
||||
"invalid_api_key": "Clave API no v\u00e1lida",
|
||||
|
@ -1,7 +1,8 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Asukoht on juba m\u00e4\u00e4ratud"
|
||||
"already_configured": "Asukoht on juba m\u00e4\u00e4ratud",
|
||||
"wrong_location": "Selles piirkonnas pole Airly m\u00f5\u00f5tejaamu."
|
||||
},
|
||||
"error": {
|
||||
"invalid_api_key": "Vigane API v\u00f5ti",
|
||||
|
@ -1,7 +1,8 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "A hely m\u00e1r konfigur\u00e1lva van"
|
||||
"already_configured": "A hely m\u00e1r konfigur\u00e1lva van",
|
||||
"wrong_location": "Ezen a ter\u00fcleten nincs Airly m\u00e9r\u0151\u00e1llom\u00e1s."
|
||||
},
|
||||
"error": {
|
||||
"invalid_api_key": "\u00c9rv\u00e9nytelen API kulcs",
|
||||
|
@ -1,7 +1,8 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Lokasi sudah dikonfigurasi"
|
||||
"already_configured": "Lokasi sudah dikonfigurasi",
|
||||
"wrong_location": "Tidak ada stasiun pengukur Airly di daerah ini."
|
||||
},
|
||||
"error": {
|
||||
"invalid_api_key": "Kunci API tidak valid",
|
||||
|
@ -1,7 +1,8 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "La posizione \u00e8 gi\u00e0 configurata"
|
||||
"already_configured": "La posizione \u00e8 gi\u00e0 configurata",
|
||||
"wrong_location": "Nessuna stazione di misurazione Airly in quest'area."
|
||||
},
|
||||
"error": {
|
||||
"invalid_api_key": "Chiave API non valida",
|
||||
|
@ -1,7 +1,8 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Locatie is al geconfigureerd"
|
||||
"already_configured": "Locatie is al geconfigureerd",
|
||||
"wrong_location": "Geen Airly meetstations in deze ruimte."
|
||||
},
|
||||
"error": {
|
||||
"invalid_api_key": "Ongeldige API-sleutel",
|
||||
|
@ -1,7 +1,8 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Plasseringen er allerede konfigurert"
|
||||
"already_configured": "Plasseringen er allerede konfigurert",
|
||||
"wrong_location": "Ingen Airly m\u00e5lestasjoner i dette omr\u00e5det."
|
||||
},
|
||||
"error": {
|
||||
"invalid_api_key": "Ugyldig API-n\u00f8kkel",
|
||||
|
@ -1,7 +1,8 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Lokalizacja jest ju\u017c skonfigurowana"
|
||||
"already_configured": "Lokalizacja jest ju\u017c skonfigurowana",
|
||||
"wrong_location": "Brak stacji pomiarowych Airly w tym rejonie"
|
||||
},
|
||||
"error": {
|
||||
"invalid_api_key": "Nieprawid\u0142owy klucz API",
|
||||
|
@ -1,7 +1,8 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Localiza\u00e7\u00e3o j\u00e1 est\u00e1 configurada"
|
||||
"already_configured": "Localiza\u00e7\u00e3o j\u00e1 est\u00e1 configurada",
|
||||
"wrong_location": "Nenhuma esta\u00e7\u00e3o de medi\u00e7\u00e3o Airly nesta \u00e1rea."
|
||||
},
|
||||
"error": {
|
||||
"invalid_api_key": "Chave de API inv\u00e1lida",
|
||||
|
@ -1,7 +1,8 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0443\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430."
|
||||
"already_configured": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0443\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430.",
|
||||
"wrong_location": "\u0412 \u044d\u0442\u043e\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u043d\u0435\u0442 \u0438\u0437\u043c\u0435\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u0441\u0442\u0430\u043d\u0446\u0438\u0439 Airly."
|
||||
},
|
||||
"error": {
|
||||
"invalid_api_key": "\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 API.",
|
||||
|
@ -1,7 +1,8 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Umiestnenie u\u017e je nakonfigurovan\u00e9"
|
||||
"already_configured": "Umiestnenie u\u017e je nakonfigurovan\u00e9",
|
||||
"wrong_location": "V tejto oblasti nie s\u00fa \u017eiadne meracie stanice Airly."
|
||||
},
|
||||
"error": {
|
||||
"invalid_api_key": "Neplatn\u00fd API k\u013e\u00fa\u010d",
|
||||
|
@ -1,7 +1,8 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Konum zaten yap\u0131land\u0131r\u0131lm\u0131\u015f"
|
||||
"already_configured": "Konum zaten yap\u0131land\u0131r\u0131lm\u0131\u015f",
|
||||
"wrong_location": "Bu b\u00f6lgede Airly \u00f6l\u00e7\u00fcm istasyonu yok."
|
||||
},
|
||||
"error": {
|
||||
"invalid_api_key": "Ge\u00e7ersiz API anahtar\u0131",
|
||||
|
@ -1,7 +1,8 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "\u5ea7\u6a19\u5df2\u7d93\u8a2d\u5b9a\u5b8c\u6210"
|
||||
"already_configured": "\u5ea7\u6a19\u5df2\u7d93\u8a2d\u5b9a\u5b8c\u6210",
|
||||
"wrong_location": "\u8a72\u5340\u57df\u6c92\u6709 Arily \u76e3\u6e2c\u7ad9\u3002"
|
||||
},
|
||||
"error": {
|
||||
"invalid_api_key": "API \u91d1\u9470\u7121\u6548",
|
||||
|
@ -17,7 +17,7 @@
|
||||
"longitude": "\u0393\u03b5\u03c9\u03b3\u03c1\u03b1\u03c6\u03b9\u03ba\u03cc \u03bc\u03ae\u03ba\u03bf\u03c2",
|
||||
"radius": "\u0391\u03ba\u03c4\u03af\u03bd\u03b1 \u03c3\u03c4\u03b1\u03b8\u03bc\u03bf\u03cd (\u03bc\u03af\u03bb\u03b9\u03b1, \u03c0\u03c1\u03bf\u03b1\u03b9\u03c1\u03b5\u03c4\u03b9\u03ba\u03cc)"
|
||||
},
|
||||
"description": "\u03a1\u03c5\u03b8\u03bc\u03af\u03c3\u03c4\u03b5 \u03c4\u03b7\u03bd \u03b5\u03bd\u03c3\u03c9\u03bc\u03ac\u03c4\u03c9\u03c3\u03b7 \u03c4\u03bf\u03c5 AirNow \u03b3\u03b9\u03b1 \u03c4\u03b7\u03bd \u03c0\u03bf\u03b9\u03cc\u03c4\u03b7\u03c4\u03b1 \u03c4\u03bf\u03c5 \u03b1\u03ad\u03c1\u03b1. \u0393\u03b9\u03b1 \u03bd\u03b1 \u03b4\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03ae\u03c3\u03b5\u03c4\u03b5 \u03c4\u03bf \u03ba\u03bb\u03b5\u03b9\u03b4\u03af API \u03bc\u03b5\u03c4\u03b1\u03b2\u03b5\u03af\u03c4\u03b5 \u03c3\u03c4\u03b7 \u03b4\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 https://docs.airnowapi.org/account/request/"
|
||||
"description": "\u0393\u03b9\u03b1 \u03bd\u03b1 \u03b4\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03ae\u03c3\u03b5\u03c4\u03b5 \u03ba\u03bb\u03b5\u03b9\u03b4\u03af API, \u03bc\u03b5\u03c4\u03b1\u03b2\u03b5\u03af\u03c4\u03b5 \u03c3\u03c4\u03b7 \u03b4\u03b9\u03b5\u03cd\u03b8\u03c5\u03bd\u03c3\u03b7 https://docs.airnowapi.org/account/request/"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
7
homeassistant/components/airnow/translations/lv.json
Normal file
7
homeassistant/components/airnow/translations/lv.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Ier\u012bce jau pievienota Home Assistant."
|
||||
}
|
||||
}
|
||||
}
|
7
homeassistant/components/airq/translations/lv.json
Normal file
7
homeassistant/components/airq/translations/lv.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Ier\u012bce jau pievienota Home Assistant."
|
||||
}
|
||||
}
|
||||
}
|
12
homeassistant/components/airq/translations/sv.json
Normal file
12
homeassistant/components/airq/translations/sv.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"config": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"ip_address": "IP-adress",
|
||||
"password": "L\u00f6senord"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
22
homeassistant/components/airq/translations/tr.json
Normal file
22
homeassistant/components/airq/translations/tr.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Cihaz zaten yap\u0131land\u0131r\u0131lm\u0131\u015f"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Ba\u011flanma hatas\u0131",
|
||||
"invalid_auth": "Ge\u00e7ersiz kimlik do\u011frulama",
|
||||
"invalid_input": "Ge\u00e7ersiz ana bilgisayar ad\u0131 veya IP adresi"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"ip_address": "IP Adresi",
|
||||
"password": "Parola"
|
||||
},
|
||||
"description": "Cihaz\u0131n IP adresini veya mDNS'sini ve \u015fifresini sa\u011flay\u0131n",
|
||||
"title": "Cihaz\u0131 tan\u0131mlay\u0131n"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
11
homeassistant/components/airq/translations/uk.json
Normal file
11
homeassistant/components/airq/translations/uk.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"config": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "\u041f\u0430\u0440\u043e\u043b\u044c"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/airthings_ble",
|
||||
"requirements": ["airthings-ble==0.5.3"],
|
||||
"dependencies": ["bluetooth"],
|
||||
"dependencies": ["bluetooth_adapters"],
|
||||
"codeowners": ["@vincegio"],
|
||||
"iot_class": "local_polling",
|
||||
"bluetooth": [
|
||||
|
@ -154,7 +154,7 @@ class AirthingsSensor(
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
coordinator: DataUpdateCoordinator,
|
||||
coordinator: DataUpdateCoordinator[AirthingsDevice],
|
||||
airthings_device: AirthingsDevice,
|
||||
entity_description: SensorEntityDescription,
|
||||
) -> None:
|
||||
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"unknown": "Neo\u010dek\u00e1van\u00e1 chyba"
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Ier\u012bce jau pievienota Home Assistant."
|
||||
}
|
||||
}
|
||||
}
|
@ -10,13 +10,13 @@
|
||||
"flow_title": "{name}",
|
||||
"step": {
|
||||
"bluetooth_confirm": {
|
||||
"description": "{name} kurulumunu yapmak istiyor musunuz?"
|
||||
"description": "{name} 'i kurmak istiyor musunuz?"
|
||||
},
|
||||
"user": {
|
||||
"data": {
|
||||
"address": "Cihaz"
|
||||
},
|
||||
"description": "Kurulum i\u00e7in bir cihaz se\u00e7in"
|
||||
"description": "Kurmak i\u00e7in bir cihaz se\u00e7in"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -12,7 +12,7 @@
|
||||
"data": {
|
||||
"host": "\u039a\u03b5\u03bd\u03c4\u03c1\u03b9\u03ba\u03cc\u03c2 \u03c5\u03c0\u03bf\u03bb\u03bf\u03b3\u03b9\u03c3\u03c4\u03ae\u03c2"
|
||||
},
|
||||
"title": "\u03a1\u03c5\u03b8\u03bc\u03af\u03c3\u03c4\u03b5 \u03c4\u03b1 \u03c3\u03c4\u03bf\u03b9\u03c7\u03b5\u03af\u03b1 \u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7\u03c2 \u03c4\u03bf\u03c5 {intergration}."
|
||||
"title": "\u03a1\u03c5\u03b8\u03bc\u03af\u03c3\u03c4\u03b5 \u03c4\u03b1 \u03c3\u03c4\u03bf\u03b9\u03c7\u03b5\u03af\u03b1 \u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7\u03c2 AirTouch 4."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
7
homeassistant/components/airtouch4/translations/lv.json
Normal file
7
homeassistant/components/airtouch4/translations/lv.json
Normal file
@ -0,0 +1,7 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Ier\u012bce jau pievienota Home Assistant."
|
||||
}
|
||||
}
|
||||
}
|
@ -61,7 +61,6 @@ DOMAIN_AIRVISUAL_PRO = "airvisual_pro"
|
||||
PLATFORMS = [Platform.SENSOR]
|
||||
|
||||
DEFAULT_ATTRIBUTION = "Data provided by AirVisual"
|
||||
DEFAULT_NODE_PRO_UPDATE_INTERVAL = timedelta(minutes=1)
|
||||
|
||||
CONFIG_SCHEMA = cv.removed(DOMAIN, raise_if_present=False)
|
||||
|
||||
@ -267,8 +266,12 @@ async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
hass.async_create_task(
|
||||
hass.config_entries.flow.async_init(
|
||||
DOMAIN,
|
||||
context={"source": source},
|
||||
data={CONF_API_KEY: entry.data[CONF_API_KEY], **geography},
|
||||
context={"source": SOURCE_IMPORT},
|
||||
data={
|
||||
"import_source": source,
|
||||
CONF_API_KEY: entry.data[CONF_API_KEY],
|
||||
**geography,
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -132,15 +132,14 @@ class AirVisualFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
LOGGER.error(err)
|
||||
errors["base"] = "unknown"
|
||||
|
||||
if errors:
|
||||
return self.async_show_form(
|
||||
step_id=error_step, data_schema=error_schema, errors=errors
|
||||
)
|
||||
|
||||
valid_keys.add(user_input[CONF_API_KEY])
|
||||
|
||||
if errors:
|
||||
return self.async_show_form(
|
||||
step_id=error_step, data_schema=error_schema, errors=errors
|
||||
)
|
||||
|
||||
existing_entry = await self.async_set_unique_id(self._geo_id)
|
||||
if existing_entry:
|
||||
if existing_entry := await self.async_set_unique_id(self._geo_id):
|
||||
self.hass.config_entries.async_update_entry(existing_entry, data=user_input)
|
||||
self.hass.async_create_task(
|
||||
self.hass.config_entries.async_reload(existing_entry.entry_id)
|
||||
@ -172,6 +171,13 @@ class AirVisualFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
"""Define the config flow to handle options."""
|
||||
return SchemaOptionsFlowHandler(config_entry, OPTIONS_FLOW)
|
||||
|
||||
async def async_step_import(self, import_data: dict[str, str]) -> FlowResult:
|
||||
"""Handle import of config entry version 1 data."""
|
||||
import_source = import_data.pop("import_source")
|
||||
if import_source == "geography_by_coords":
|
||||
return await self.async_step_geography_by_coords(import_data)
|
||||
return await self.async_step_geography_by_name(import_data)
|
||||
|
||||
async def async_step_geography_by_coords(
|
||||
self, user_input: dict[str, str] | None = None
|
||||
) -> FlowResult:
|
||||
|
@ -19,11 +19,8 @@ from homeassistant.const import (
|
||||
CONF_LONGITUDE,
|
||||
CONF_SHOW_ON_MAP,
|
||||
CONF_STATE,
|
||||
PERCENTAGE,
|
||||
UnitOfTemperature,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.entity import EntityCategory
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
|
||||
|
||||
@ -37,17 +34,8 @@ ATTR_POLLUTANT_UNIT = "pollutant_unit"
|
||||
ATTR_REGION = "region"
|
||||
|
||||
SENSOR_KIND_AQI = "air_quality_index"
|
||||
SENSOR_KIND_BATTERY_LEVEL = "battery_level"
|
||||
SENSOR_KIND_CO2 = "carbon_dioxide"
|
||||
SENSOR_KIND_HUMIDITY = "humidity"
|
||||
SENSOR_KIND_LEVEL = "air_pollution_level"
|
||||
SENSOR_KIND_PM_0_1 = "particulate_matter_0_1"
|
||||
SENSOR_KIND_PM_1_0 = "particulate_matter_1_0"
|
||||
SENSOR_KIND_PM_2_5 = "particulate_matter_2_5"
|
||||
SENSOR_KIND_POLLUTANT = "main_pollutant"
|
||||
SENSOR_KIND_SENSOR_LIFE = "sensor_life"
|
||||
SENSOR_KIND_TEMPERATURE = "temperature"
|
||||
SENSOR_KIND_VOC = "voc"
|
||||
|
||||
GEOGRAPHY_SENSOR_DESCRIPTIONS = (
|
||||
SensorEntityDescription(
|
||||
@ -82,70 +70,6 @@ GEOGRAPHY_SENSOR_DESCRIPTIONS = (
|
||||
)
|
||||
GEOGRAPHY_SENSOR_LOCALES = {"cn": "Chinese", "us": "U.S."}
|
||||
|
||||
NODE_PRO_SENSOR_DESCRIPTIONS = (
|
||||
SensorEntityDescription(
|
||||
key=SENSOR_KIND_AQI,
|
||||
name="Air quality index",
|
||||
device_class=SensorDeviceClass.AQI,
|
||||
native_unit_of_measurement="AQI",
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=SENSOR_KIND_BATTERY_LEVEL,
|
||||
name="Battery",
|
||||
device_class=SensorDeviceClass.BATTERY,
|
||||
entity_category=EntityCategory.DIAGNOSTIC,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=SENSOR_KIND_CO2,
|
||||
name="C02",
|
||||
device_class=SensorDeviceClass.CO2,
|
||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=SENSOR_KIND_HUMIDITY,
|
||||
name="Humidity",
|
||||
device_class=SensorDeviceClass.HUMIDITY,
|
||||
native_unit_of_measurement=PERCENTAGE,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=SENSOR_KIND_PM_0_1,
|
||||
name="PM 0.1",
|
||||
device_class=SensorDeviceClass.PM1,
|
||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=SENSOR_KIND_PM_1_0,
|
||||
name="PM 1.0",
|
||||
device_class=SensorDeviceClass.PM10,
|
||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=SENSOR_KIND_PM_2_5,
|
||||
name="PM 2.5",
|
||||
device_class=SensorDeviceClass.PM25,
|
||||
native_unit_of_measurement=CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=SENSOR_KIND_TEMPERATURE,
|
||||
name="Temperature",
|
||||
device_class=SensorDeviceClass.TEMPERATURE,
|
||||
native_unit_of_measurement=UnitOfTemperature.CELSIUS,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
SensorEntityDescription(
|
||||
key=SENSOR_KIND_VOC,
|
||||
name="VOC",
|
||||
device_class=SensorDeviceClass.VOLATILE_ORGANIC_COMPOUNDS,
|
||||
native_unit_of_measurement=CONCENTRATION_PARTS_PER_MILLION,
|
||||
state_class=SensorStateClass.MEASUREMENT,
|
||||
),
|
||||
)
|
||||
|
||||
STATE_POLLUTANT_LABEL_CO = "co"
|
||||
STATE_POLLUTANT_LABEL_N2 = "n2"
|
||||
|
@ -22,12 +22,6 @@
|
||||
"country": "\u0421\u0442\u0440\u0430\u043d\u0430"
|
||||
}
|
||||
},
|
||||
"node_pro": {
|
||||
"data": {
|
||||
"ip_address": "\u0425\u043e\u0441\u0442",
|
||||
"password": "\u041f\u0430\u0440\u043e\u043b\u0430"
|
||||
}
|
||||
},
|
||||
"reauth_confirm": {
|
||||
"data": {
|
||||
"api_key": "API \u043a\u043b\u044e\u0447"
|
||||
|
@ -30,14 +30,6 @@
|
||||
"description": "Utilitza l'API d'AirVisual per monitoritzar un/a ciutat/estat/pa\u00eds",
|
||||
"title": "Configura una ubicaci\u00f3 geogr\u00e0fica"
|
||||
},
|
||||
"node_pro": {
|
||||
"data": {
|
||||
"ip_address": "Amfitri\u00f3",
|
||||
"password": "Contrasenya"
|
||||
},
|
||||
"description": "Monitoritza una unitat personal d'AirVisual. Pots obtenir la contrasenya des de la interf\u00edcie d'usuari (UI) de la unitat.",
|
||||
"title": "Configuraci\u00f3 d'AirVisual Node/Pro"
|
||||
},
|
||||
"reauth_confirm": {
|
||||
"data": {
|
||||
"api_key": "Clau API"
|
||||
|
@ -24,13 +24,6 @@
|
||||
"country": "Zem\u011b"
|
||||
}
|
||||
},
|
||||
"node_pro": {
|
||||
"data": {
|
||||
"ip_address": "Hostitel",
|
||||
"password": "Heslo"
|
||||
},
|
||||
"title": "Nastaven\u00ed AirVisual Node/Pro"
|
||||
},
|
||||
"reauth_confirm": {
|
||||
"data": {
|
||||
"api_key": "Kl\u00ed\u010d API"
|
||||
|
@ -30,14 +30,6 @@
|
||||
"description": "Verwende die AirVisual Cloud API, um ein(e) Stadt/Bundesland/Land zu \u00fcberwachen.",
|
||||
"title": "Konfiguriere einen Standort"
|
||||
},
|
||||
"node_pro": {
|
||||
"data": {
|
||||
"ip_address": "Host",
|
||||
"password": "Passwort"
|
||||
},
|
||||
"description": "\u00dcberwache eine pers\u00f6nliche AirVisual-Einheit. Das Passwort kann von der Benutzeroberfl\u00e4che des Ger\u00e4ts abgerufen werden.",
|
||||
"title": "Konfiguriere einen AirVisual Node/Pro"
|
||||
},
|
||||
"reauth_confirm": {
|
||||
"data": {
|
||||
"api_key": "API-Schl\u00fcssel"
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "\u0397 \u03c4\u03bf\u03c0\u03bf\u03b8\u03b5\u03c3\u03af\u03b1 \u03ad\u03c7\u03b5\u03b9 \u03ae\u03b4\u03b7 \u03b4\u03b9\u03b1\u03bc\u03bf\u03c1\u03c6\u03c9\u03b8\u03b5\u03af \u03ae \u03c4\u03bf Node/Pro ID \u03b5\u03af\u03bd\u03b1\u03b9 \u03ae\u03b4\u03b7 \u03ba\u03b1\u03c4\u03b1\u03c7\u03c9\u03c1\u03b7\u03bc\u03ad\u03bd\u03bf.",
|
||||
"already_configured": "\u0397 \u03c4\u03bf\u03c0\u03bf\u03b8\u03b5\u03c3\u03af\u03b1 \u03ad\u03c7\u03b5\u03b9 \u03ae\u03b4\u03b7 \u03b4\u03b9\u03b1\u03bc\u03bf\u03c1\u03c6\u03c9\u03b8\u03b5\u03af",
|
||||
"reauth_successful": "\u039f \u03b5\u03ba \u03bd\u03ad\u03bf\u03c5 \u03ad\u03bb\u03b5\u03b3\u03c7\u03bf\u03c2 \u03c4\u03b1\u03c5\u03c4\u03cc\u03c4\u03b7\u03c4\u03b1\u03c2 \u03ae\u03c4\u03b1\u03bd \u03b5\u03c0\u03b9\u03c4\u03c5\u03c7\u03ae\u03c2"
|
||||
},
|
||||
"error": {
|
||||
@ -30,14 +30,6 @@
|
||||
"description": "\u03a7\u03c1\u03b7\u03c3\u03b9\u03bc\u03bf\u03c0\u03bf\u03b9\u03ae\u03c3\u03c4\u03b5 \u03c4\u03bf AirVisual cloud API \u03b3\u03b9\u03b1 \u03bd\u03b1 \u03c0\u03b1\u03c1\u03b1\u03ba\u03bf\u03bb\u03bf\u03c5\u03b8\u03b5\u03af\u03c4\u03b5 \u03bc\u03b9\u03b1 \u03c0\u03cc\u03bb\u03b7/\u03c0\u03bf\u03bb\u03b9\u03c4\u03b5\u03af\u03b1/\u03c7\u03ce\u03c1\u03b1.",
|
||||
"title": "\u0394\u03b9\u03b1\u03bc\u03cc\u03c1\u03c6\u03c9\u03c3\u03b7 \u03b3\u03b5\u03c9\u03b3\u03c1\u03b1\u03c6\u03af\u03b1\u03c2"
|
||||
},
|
||||
"node_pro": {
|
||||
"data": {
|
||||
"ip_address": "\u039a\u03b5\u03bd\u03c4\u03c1\u03b9\u03ba\u03cc\u03c2 \u03c5\u03c0\u03bf\u03bb\u03bf\u03b3\u03b9\u03c3\u03c4\u03ae\u03c2",
|
||||
"password": "\u039a\u03c9\u03b4\u03b9\u03ba\u03cc\u03c2 \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2"
|
||||
},
|
||||
"description": "\u03a0\u03b1\u03c1\u03b1\u03ba\u03bf\u03bb\u03bf\u03c5\u03b8\u03ae\u03c3\u03c4\u03b5 \u03bc\u03b9\u03b1 \u03c0\u03c1\u03bf\u03c3\u03c9\u03c0\u03b9\u03ba\u03ae \u03bc\u03bf\u03bd\u03ac\u03b4\u03b1 AirVisual. \u039f \u03ba\u03c9\u03b4\u03b9\u03ba\u03cc\u03c2 \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2 \u03bc\u03c0\u03bf\u03c1\u03b5\u03af \u03bd\u03b1 \u03b1\u03bd\u03b1\u03ba\u03c4\u03b7\u03b8\u03b5\u03af \u03b1\u03c0\u03cc \u03c4\u03bf UI \u03c4\u03b7\u03c2 \u03bc\u03bf\u03bd\u03ac\u03b4\u03b1\u03c2.",
|
||||
"title": "\u0394\u03b9\u03b1\u03bc\u03cc\u03c1\u03c6\u03c9\u03c3\u03b7 \u03b5\u03bd\u03cc\u03c2 \u03ba\u03cc\u03bc\u03b2\u03bf\u03c5 AirVisual Node/Pro"
|
||||
},
|
||||
"reauth_confirm": {
|
||||
"data": {
|
||||
"api_key": "\u039a\u03bb\u03b5\u03b9\u03b4\u03af API"
|
||||
|
@ -30,14 +30,6 @@
|
||||
"description": "Use the AirVisual cloud API to monitor a city/state/country.",
|
||||
"title": "Configure a Geography"
|
||||
},
|
||||
"node_pro": {
|
||||
"data": {
|
||||
"ip_address": "Host",
|
||||
"password": "Password"
|
||||
},
|
||||
"description": "Monitor a personal AirVisual unit. The password can be retrieved from the unit's UI.",
|
||||
"title": "Configure an AirVisual Node/Pro"
|
||||
},
|
||||
"reauth_confirm": {
|
||||
"data": {
|
||||
"api_key": "API Key"
|
||||
|
@ -22,14 +22,6 @@
|
||||
"description": "Utilice la API en la nube de AirVisual para monitorear una ciudad/estado/pa\u00eds.",
|
||||
"title": "Configurar una geograf\u00eda"
|
||||
},
|
||||
"node_pro": {
|
||||
"data": {
|
||||
"ip_address": "Direcci\u00f3n IP/nombre de host de la unidad",
|
||||
"password": "Contrase\u00f1a de la unidad"
|
||||
},
|
||||
"description": "Monitoree una unidad AirVisual personal. La contrase\u00f1a se puede recuperar de la interfaz de usuario de la unidad.",
|
||||
"title": "Configurar un AirVisual Node/Pro"
|
||||
},
|
||||
"reauth_confirm": {
|
||||
"title": "Vuelva a autenticar AirVisual"
|
||||
},
|
||||
|
@ -30,14 +30,6 @@
|
||||
"description": "Usar la API de la nube de AirVisual para supervisar una ciudad/estado/pa\u00eds.",
|
||||
"title": "Configurar una geograf\u00eda"
|
||||
},
|
||||
"node_pro": {
|
||||
"data": {
|
||||
"ip_address": "Host",
|
||||
"password": "Contrase\u00f1a"
|
||||
},
|
||||
"description": "Supervisar una unidad AirVisual personal. La contrase\u00f1a se puede recuperar desde la IU de la unidad.",
|
||||
"title": "Configurar un AirVisual Node/Pro"
|
||||
},
|
||||
"reauth_confirm": {
|
||||
"data": {
|
||||
"api_key": "Clave API"
|
||||
|
@ -30,14 +30,6 @@
|
||||
"description": "Kasuta AirVisual pilve API-t linna/osariigi/riigi j\u00e4lgimiseks.",
|
||||
"title": "Seadista Geography sidumine"
|
||||
},
|
||||
"node_pro": {
|
||||
"data": {
|
||||
"ip_address": "\u00dcksuse IP-aadress / hostinimi",
|
||||
"password": "Salas\u00f5na"
|
||||
},
|
||||
"description": "J\u00e4lgige isiklikku AirVisual-seadet. Parooli saab hankida seadme kasutajaliidese kaudu.",
|
||||
"title": "Seadistage AirVisual Node / Pro"
|
||||
},
|
||||
"reauth_confirm": {
|
||||
"data": {
|
||||
"api_key": "API v\u00f5ti"
|
||||
|
@ -2,13 +2,6 @@
|
||||
"config": {
|
||||
"error": {
|
||||
"general_error": "Tapahtui tuntematon virhe."
|
||||
},
|
||||
"step": {
|
||||
"node_pro": {
|
||||
"data": {
|
||||
"password": "Salasana"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -30,14 +30,6 @@
|
||||
"description": "Utilisez l'API cloud AirVisual pour surveiller une ville / un \u00e9tat / un pays.",
|
||||
"title": "Configurer un lieu g\u00e9ographique"
|
||||
},
|
||||
"node_pro": {
|
||||
"data": {
|
||||
"ip_address": "H\u00f4te",
|
||||
"password": "Mot de passe"
|
||||
},
|
||||
"description": "Surveillez une unit\u00e9 personnelle AirVisual. Le mot de passe peut \u00eatre r\u00e9cup\u00e9r\u00e9 dans l'interface utilisateur de l'unit\u00e9.",
|
||||
"title": "Configurer un noeud AirVisual Pro"
|
||||
},
|
||||
"reauth_confirm": {
|
||||
"data": {
|
||||
"api_key": "Cl\u00e9 d'API"
|
||||
|
@ -22,13 +22,6 @@
|
||||
"api_key": "\u05de\u05e4\u05ea\u05d7 API"
|
||||
}
|
||||
},
|
||||
"node_pro": {
|
||||
"data": {
|
||||
"ip_address": "\u05de\u05d0\u05e8\u05d7",
|
||||
"password": "\u05e1\u05d9\u05e1\u05de\u05d4"
|
||||
},
|
||||
"description": "\u05e2\u05e7\u05d5\u05d1 \u05d0\u05d7\u05e8 \u05d9\u05d7\u05d9\u05d3\u05ea AirVisual \u05d0\u05d9\u05e9\u05d9\u05ea. \u05e0\u05d9\u05ea\u05df \u05dc\u05d0\u05d7\u05d6\u05e8 \u05d0\u05ea \u05d4\u05e1\u05d9\u05e1\u05de\u05d4 \u05de\u05de\u05e9\u05e7 \u05d4\u05de\u05e9\u05ea\u05de\u05e9 \u05e9\u05dc \u05d4\u05d9\u05d7\u05d9\u05d3\u05d4."
|
||||
},
|
||||
"reauth_confirm": {
|
||||
"data": {
|
||||
"api_key": "\u05de\u05e4\u05ea\u05d7 API"
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user