mirror of
https://github.com/home-assistant/core.git
synced 2025-07-23 21:27:38 +00:00
Merge pull request #45911 from home-assistant/rc
This commit is contained in:
commit
1eff2ab22b
42
.coveragerc
42
.coveragerc
@ -29,6 +29,8 @@ omit =
|
||||
homeassistant/components/agent_dvr/camera.py
|
||||
homeassistant/components/agent_dvr/const.py
|
||||
homeassistant/components/agent_dvr/helpers.py
|
||||
homeassistant/components/airnow/__init__.py
|
||||
homeassistant/components/airnow/sensor.py
|
||||
homeassistant/components/airvisual/__init__.py
|
||||
homeassistant/components/airvisual/air_quality.py
|
||||
homeassistant/components/airvisual/sensor.py
|
||||
@ -142,7 +144,7 @@ omit =
|
||||
homeassistant/components/co2signal/*
|
||||
homeassistant/components/coinbase/*
|
||||
homeassistant/components/comed_hourly_pricing/sensor.py
|
||||
homeassistant/components/comfoconnect/*
|
||||
homeassistant/components/comfoconnect/fan.py
|
||||
homeassistant/components/concord232/alarm_control_panel.py
|
||||
homeassistant/components/concord232/binary_sensor.py
|
||||
homeassistant/components/control4/__init__.py
|
||||
@ -213,7 +215,11 @@ omit =
|
||||
homeassistant/components/ecobee/notify.py
|
||||
homeassistant/components/ecobee/sensor.py
|
||||
homeassistant/components/ecobee/weather.py
|
||||
homeassistant/components/econet/*
|
||||
homeassistant/components/econet/__init__.py
|
||||
homeassistant/components/econet/binary_sensor.py
|
||||
homeassistant/components/econet/const.py
|
||||
homeassistant/components/econet/sensor.py
|
||||
homeassistant/components/econet/water_heater.py
|
||||
homeassistant/components/ecovacs/*
|
||||
homeassistant/components/edl21/*
|
||||
homeassistant/components/eddystone_temperature/sensor.py
|
||||
@ -298,8 +304,8 @@ omit =
|
||||
homeassistant/components/folder_watcher/*
|
||||
homeassistant/components/foobot/sensor.py
|
||||
homeassistant/components/fortios/device_tracker.py
|
||||
homeassistant/components/foscam/__init__.py
|
||||
homeassistant/components/foscam/camera.py
|
||||
homeassistant/components/foscam/const.py
|
||||
homeassistant/components/foursquare/*
|
||||
homeassistant/components/free_mobile/notify.py
|
||||
homeassistant/components/freebox/__init__.py
|
||||
@ -308,6 +314,9 @@ omit =
|
||||
homeassistant/components/freebox/sensor.py
|
||||
homeassistant/components/freebox/switch.py
|
||||
homeassistant/components/fritz/device_tracker.py
|
||||
homeassistant/components/fritzbox_callmonitor/__init__.py
|
||||
homeassistant/components/fritzbox_callmonitor/const.py
|
||||
homeassistant/components/fritzbox_callmonitor/base.py
|
||||
homeassistant/components/fritzbox_callmonitor/sensor.py
|
||||
homeassistant/components/fritzbox_netmonitor/sensor.py
|
||||
homeassistant/components/fronius/sensor.py
|
||||
@ -356,7 +365,10 @@ omit =
|
||||
homeassistant/components/hangouts/hangouts_bot.py
|
||||
homeassistant/components/hangouts/hangups_utils.py
|
||||
homeassistant/components/harman_kardon_avr/media_player.py
|
||||
homeassistant/components/harmony/*
|
||||
homeassistant/components/harmony/const.py
|
||||
homeassistant/components/harmony/data.py
|
||||
homeassistant/components/harmony/remote.py
|
||||
homeassistant/components/harmony/util.py
|
||||
homeassistant/components/haveibeenpwned/sensor.py
|
||||
homeassistant/components/hdmi_cec/*
|
||||
homeassistant/components/heatmiser/climate.py
|
||||
@ -578,13 +590,7 @@ omit =
|
||||
homeassistant/components/neato/vacuum.py
|
||||
homeassistant/components/nederlandse_spoorwegen/sensor.py
|
||||
homeassistant/components/nello/lock.py
|
||||
homeassistant/components/nest/__init__.py
|
||||
homeassistant/components/nest/api.py
|
||||
homeassistant/components/nest/binary_sensor.py
|
||||
homeassistant/components/nest/camera.py
|
||||
homeassistant/components/nest/climate.py
|
||||
homeassistant/components/nest/legacy/*
|
||||
homeassistant/components/nest/sensor.py
|
||||
homeassistant/components/netatmo/__init__.py
|
||||
homeassistant/components/netatmo/api.py
|
||||
homeassistant/components/netatmo/camera.py
|
||||
@ -629,6 +635,11 @@ omit =
|
||||
homeassistant/components/omnilogic/__init__.py
|
||||
homeassistant/components/omnilogic/common.py
|
||||
homeassistant/components/omnilogic/sensor.py
|
||||
homeassistant/components/ondilo_ico/__init__.py
|
||||
homeassistant/components/ondilo_ico/api.py
|
||||
homeassistant/components/ondilo_ico/const.py
|
||||
homeassistant/components/ondilo_ico/oauth_impl.py
|
||||
homeassistant/components/ondilo_ico/sensor.py
|
||||
homeassistant/components/onkyo/media_player.py
|
||||
homeassistant/components/onvif/__init__.py
|
||||
homeassistant/components/onvif/base.py
|
||||
@ -690,8 +701,6 @@ omit =
|
||||
homeassistant/components/pjlink/media_player.py
|
||||
homeassistant/components/plaato/*
|
||||
homeassistant/components/plex/media_player.py
|
||||
homeassistant/components/plex/models.py
|
||||
homeassistant/components/plex/sensor.py
|
||||
homeassistant/components/plum_lightpad/light.py
|
||||
homeassistant/components/pocketcasts/sensor.py
|
||||
homeassistant/components/point/*
|
||||
@ -706,7 +715,6 @@ omit =
|
||||
homeassistant/components/prowl/notify.py
|
||||
homeassistant/components/proxmoxve/*
|
||||
homeassistant/components/proxy/camera.py
|
||||
homeassistant/components/ptvsd/*
|
||||
homeassistant/components/pulseaudio_loopback/switch.py
|
||||
homeassistant/components/pushbullet/notify.py
|
||||
homeassistant/components/pushbullet/sensor.py
|
||||
@ -790,11 +798,9 @@ omit =
|
||||
homeassistant/components/shodan/sensor.py
|
||||
homeassistant/components/shelly/__init__.py
|
||||
homeassistant/components/shelly/binary_sensor.py
|
||||
homeassistant/components/shelly/cover.py
|
||||
homeassistant/components/shelly/entity.py
|
||||
homeassistant/components/shelly/light.py
|
||||
homeassistant/components/shelly/sensor.py
|
||||
homeassistant/components/shelly/switch.py
|
||||
homeassistant/components/shelly/utils.py
|
||||
homeassistant/components/sht31/sensor.py
|
||||
homeassistant/components/sigfox/sensor.py
|
||||
@ -837,7 +843,8 @@ omit =
|
||||
homeassistant/components/soma/cover.py
|
||||
homeassistant/components/soma/sensor.py
|
||||
homeassistant/components/somfy/*
|
||||
homeassistant/components/somfy_mylink/*
|
||||
homeassistant/components/somfy_mylink/__init__.py
|
||||
homeassistant/components/somfy_mylink/cover.py
|
||||
homeassistant/components/sonos/*
|
||||
homeassistant/components/sony_projector/switch.py
|
||||
homeassistant/components/spc/*
|
||||
@ -1090,6 +1097,9 @@ omit =
|
||||
homeassistant/components/zoneminder/*
|
||||
homeassistant/components/supla/*
|
||||
homeassistant/components/zwave/util.py
|
||||
homeassistant/components/zwave_js/discovery.py
|
||||
homeassistant/components/zwave_js/light.py
|
||||
homeassistant/components/zwave_js/sensor.py
|
||||
|
||||
[report]
|
||||
# Regexes for lines to exclude from consideration
|
||||
|
43
.github/workflows/ci.yaml
vendored
43
.github/workflows/ci.yaml
vendored
@ -11,7 +11,7 @@ on:
|
||||
|
||||
env:
|
||||
CACHE_VERSION: 1
|
||||
DEFAULT_PYTHON: 3.7
|
||||
DEFAULT_PYTHON: 3.8
|
||||
PRE_COMMIT_HOME: ~/.cache/pre-commit
|
||||
|
||||
jobs:
|
||||
@ -521,13 +521,12 @@ jobs:
|
||||
needs: prepare-tests
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.7]
|
||||
python-version: [3.8]
|
||||
container: homeassistant/ci-azure:${{ matrix.python-version }}
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v2
|
||||
- name:
|
||||
Restore full Python ${{ matrix.python-version }} virtual environment
|
||||
- name: Restore full Python ${{ matrix.python-version }} virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
@ -585,13 +584,12 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.7, 3.8]
|
||||
python-version: [3.8, 3.9]
|
||||
container: homeassistant/ci-azure:${{ matrix.python-version }}
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v2
|
||||
- name:
|
||||
Restore full Python ${{ matrix.python-version }} virtual environment
|
||||
- name: Restore full Python ${{ matrix.python-version }} virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
@ -605,10 +603,13 @@ jobs:
|
||||
${{ env.CACHE_VERSION}}-${{ runner.os }}-venv-${{ matrix.python-version }}-${{ hashFiles('requirements_test.txt') }}-${{ hashFiles('requirements_all.txt') }}
|
||||
${{ env.CACHE_VERSION}}-${{ runner.os }}-venv-${{ matrix.python-version }}-${{ hashFiles('requirements_test.txt') }}
|
||||
${{ env.CACHE_VERSION}}-${{ runner.os }}-venv-${{ matrix.python-version }}-
|
||||
- name:
|
||||
Create full Python ${{ matrix.python-version }} virtual environment
|
||||
- name: Create full Python ${{ matrix.python-version }} virtual environment
|
||||
if: steps.cache-venv.outputs.cache-hit != 'true'
|
||||
run: |
|
||||
# Temporary addition of cmake, needed to build some Python 3.9 packages
|
||||
apt-get update
|
||||
apt-get -y install cmake
|
||||
|
||||
python -m venv venv
|
||||
. venv/bin/activate
|
||||
pip install -U "pip<20.3" setuptools wheel
|
||||
@ -622,13 +623,12 @@ jobs:
|
||||
needs: prepare-tests
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.7]
|
||||
python-version: [3.8]
|
||||
container: homeassistant/ci-azure:${{ matrix.python-version }}
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v2
|
||||
- name:
|
||||
Restore full Python ${{ matrix.python-version }} virtual environment
|
||||
- name: Restore full Python ${{ matrix.python-version }} virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
@ -657,13 +657,12 @@ jobs:
|
||||
needs: prepare-tests
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.7]
|
||||
python-version: [3.8]
|
||||
container: homeassistant/ci-azure:${{ matrix.python-version }}
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v2
|
||||
- name:
|
||||
Restore full Python ${{ matrix.python-version }} virtual environment
|
||||
- name: Restore full Python ${{ matrix.python-version }} virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
@ -692,15 +691,14 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
group: [1, 2, 3, 4]
|
||||
python-version: [3.7, 3.8]
|
||||
python-version: [3.8, 3.9]
|
||||
name: >-
|
||||
Run tests Python ${{ matrix.python-version }} (group ${{ matrix.group }})
|
||||
container: homeassistant/ci-azure:${{ matrix.python-version }}
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v2
|
||||
- name:
|
||||
Restore full Python ${{ matrix.python-version }} virtual environment
|
||||
- name: Restore full Python ${{ matrix.python-version }} virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
@ -741,7 +739,7 @@ jobs:
|
||||
-p no:sugar \
|
||||
tests
|
||||
- name: Upload coverage artifact
|
||||
uses: actions/upload-artifact@v2.2.1
|
||||
uses: actions/upload-artifact@v2.2.2
|
||||
with:
|
||||
name: coverage-${{ matrix.python-version }}-group${{ matrix.group }}
|
||||
path: .coverage
|
||||
@ -755,13 +753,12 @@ jobs:
|
||||
needs: pytest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [3.7]
|
||||
python-version: [3.8]
|
||||
container: homeassistant/ci-azure:${{ matrix.python-version }}
|
||||
steps:
|
||||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v2
|
||||
- name:
|
||||
Restore full Python ${{ matrix.python-version }} virtual environment
|
||||
- name: Restore full Python ${{ matrix.python-version }} virtual environment
|
||||
id: cache-venv
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
@ -785,4 +782,4 @@ jobs:
|
||||
coverage report --fail-under=94
|
||||
coverage xml
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v1.1.1
|
||||
uses: codecov/codecov-action@v1.2.1
|
||||
|
2
.github/workflows/lock.yml
vendored
2
.github/workflows/lock.yml
vendored
@ -9,7 +9,7 @@ jobs:
|
||||
lock:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: dessant/lock-threads@v2.0.1
|
||||
- uses: dessant/lock-threads@v2.0.3
|
||||
with:
|
||||
github-token: ${{ github.token }}
|
||||
issue-lock-inactive-days: "30"
|
||||
|
69
.github/workflows/stale.yml
vendored
69
.github/workflows/stale.yml
vendored
@ -4,23 +4,27 @@ name: Stale
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 * * * *"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
# The 90 day stale policy
|
||||
# Used for: Everything (unless 30 day policy below beats it)
|
||||
- name: 90 days stale policy
|
||||
uses: actions/stale@v3.0.14
|
||||
# Used for:
|
||||
# - Issues & PRs
|
||||
# - No PRs marked as no-stale
|
||||
# - No issues marked as no-stale or help-wanted
|
||||
- name: 90 days stale issues & PRs policy
|
||||
uses: actions/stale@v3.0.15
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 90
|
||||
days-before-close: 7
|
||||
operations-per-run: 25
|
||||
operations-per-run: 150
|
||||
remove-stale-when-updated: true
|
||||
stale-issue-label: "stale"
|
||||
exempt-issue-labels: "no-stale,Help%20wanted,help-wanted"
|
||||
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
|
||||
@ -43,22 +47,48 @@ jobs:
|
||||
|
||||
Thank you for your contributions.
|
||||
|
||||
# The 30 day stale policy
|
||||
# The 30 day stale policy for PRS
|
||||
# Used for:
|
||||
# - Issues that are pending more information (incomplete issues)
|
||||
# - PRs that are not marked as new-integration
|
||||
- name: 30 days stale policy
|
||||
uses: actions/stale@v3.0.14
|
||||
# - PRs
|
||||
# - No PRs marked as no-stale or new-integrations
|
||||
# - No issues (-1)
|
||||
- name: 30 days stale PRs policy
|
||||
uses: actions/stale@v3.0.15
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# PRs have a CLA signed label, we can misuse it to apply this policy
|
||||
only-labels: "cla-signed,needs-more-information"
|
||||
days-before-stale: 30
|
||||
days-before-close: 7
|
||||
operations-per-run: 5
|
||||
days-before-issue-close: -1
|
||||
operations-per-run: 50
|
||||
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.
|
||||
|
||||
Thank you for your contributions.
|
||||
|
||||
# The 30 day stale policy for issues
|
||||
# Used for:
|
||||
# - Issues that are pending more information (incomplete issues)
|
||||
# - No Issues marked as no-stale or help-wanted
|
||||
# - No PRs (-1)
|
||||
- name: Needs more information stale issues policy
|
||||
uses: actions/stale@v3.0.15
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
only-labels: "needs-more-information"
|
||||
days-before-stale: 14
|
||||
days-before-close: 7
|
||||
days-before-pr-close: -1
|
||||
operations-per-run: 50
|
||||
remove-stale-when-updated: true
|
||||
stale-issue-label: "stale"
|
||||
exempt-issue-labels: "no-stale,Help%20wanted,help-wanted"
|
||||
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
|
||||
@ -71,14 +101,3 @@ jobs:
|
||||
|
||||
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 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.
|
||||
|
||||
Thank you for your contributions.
|
||||
|
@ -3,7 +3,7 @@ repos:
|
||||
rev: v2.7.2
|
||||
hooks:
|
||||
- id: pyupgrade
|
||||
args: [--py37-plus]
|
||||
args: [--py38-plus]
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 20.8b1
|
||||
hooks:
|
||||
@ -13,14 +13,15 @@ repos:
|
||||
- --quiet
|
||||
files: ^((homeassistant|script|tests)/.+)?[^/]+\.py$
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
rev: v1.17.1
|
||||
rev: v2.0.0
|
||||
hooks:
|
||||
- id: codespell
|
||||
args:
|
||||
- --ignore-words-list=hass,alot,datas,dof,dur,farenheit,hist,iff,ines,ist,lightsensor,mut,nd,pres,referer,ser,serie,te,technik,ue,uint,visability,wan,wanna,withing,iam,incomfort
|
||||
- --ignore-words-list=hass,alot,datas,dof,dur,ether,farenheit,hist,iff,ines,ist,lightsensor,mut,nd,pres,referer,ser,serie,te,technik,ue,uint,visability,wan,wanna,withing,iam,incomfort
|
||||
- --skip="./.*,*.csv,*.json"
|
||||
- --quiet-level=2
|
||||
exclude_types: [csv, json]
|
||||
exclude: ^tests/fixtures/
|
||||
- repo: https://gitlab.com/pycqa/flake8
|
||||
rev: 3.8.4
|
||||
hooks:
|
||||
|
@ -4,7 +4,7 @@ build:
|
||||
image: latest
|
||||
|
||||
python:
|
||||
version: 3.7
|
||||
version: 3.8
|
||||
setup_py_install: true
|
||||
|
||||
requirements_file: requirements_docs.txt
|
||||
|
2
.vscode/settings.default.json
vendored
2
.vscode/settings.default.json
vendored
@ -5,5 +5,5 @@
|
||||
// https://github.com/microsoft/vscode-python/issues/14067
|
||||
"python.testing.pytestArgs": ["--no-cov"],
|
||||
// https://code.visualstudio.com/docs/python/testing#_pytest-configuration-settings
|
||||
"python.testing.pytestEnabled": true
|
||||
"python.testing.pytestEnabled": false
|
||||
}
|
||||
|
20
CODEOWNERS
20
CODEOWNERS
@ -26,6 +26,7 @@ homeassistant/components/adguard/* @frenck
|
||||
homeassistant/components/advantage_air/* @Bre77
|
||||
homeassistant/components/agent_dvr/* @ispysoftware
|
||||
homeassistant/components/airly/* @bieniu
|
||||
homeassistant/components/airnow/* @asymworks
|
||||
homeassistant/components/airvisual/* @bachya
|
||||
homeassistant/components/alarmdecoder/* @ajschmidt8
|
||||
homeassistant/components/alexa/* @home-assistant/cloud @ochlocracy
|
||||
@ -55,7 +56,6 @@ homeassistant/components/auth/* @home-assistant/core
|
||||
homeassistant/components/automation/* @home-assistant/core
|
||||
homeassistant/components/avea/* @pattyland
|
||||
homeassistant/components/awair/* @ahayworth @danielsjf
|
||||
homeassistant/components/aws/* @awarecan
|
||||
homeassistant/components/axis/* @Kane610
|
||||
homeassistant/components/azure_devops/* @timmo001
|
||||
homeassistant/components/azure_event_hub/* @eavanvalkenburg
|
||||
@ -107,6 +107,7 @@ homeassistant/components/derivative/* @afaucogney
|
||||
homeassistant/components/device_automation/* @home-assistant/core
|
||||
homeassistant/components/devolo_home_control/* @2Fake @Shutgun
|
||||
homeassistant/components/dexcom/* @gagebenne
|
||||
homeassistant/components/dhcp/* @bdraco
|
||||
homeassistant/components/digital_ocean/* @fabaff
|
||||
homeassistant/components/directv/* @ctalkington
|
||||
homeassistant/components/discogs/* @thibmaek
|
||||
@ -119,6 +120,7 @@ homeassistant/components/dweet/* @fabaff
|
||||
homeassistant/components/dynalite/* @ziv1234
|
||||
homeassistant/components/eafm/* @Jc2k
|
||||
homeassistant/components/ecobee/* @marthoc
|
||||
homeassistant/components/econet/* @vangorra @w1ll1am23
|
||||
homeassistant/components/ecovacs/* @OverloadUT
|
||||
homeassistant/components/edl21/* @mtdcr
|
||||
homeassistant/components/egardia/* @jeroenterheerdt
|
||||
@ -179,7 +181,7 @@ homeassistant/components/griddy/* @bdraco
|
||||
homeassistant/components/group/* @home-assistant/core
|
||||
homeassistant/components/growatt_server/* @indykoning
|
||||
homeassistant/components/guardian/* @bachya
|
||||
homeassistant/components/harmony/* @ehendrix23 @bramkragten @bdraco
|
||||
homeassistant/components/harmony/* @ehendrix23 @bramkragten @bdraco @mkeesey
|
||||
homeassistant/components/hassio/* @home-assistant/supervisor
|
||||
homeassistant/components/hdmi_cec/* @newAM
|
||||
homeassistant/components/heatmiser/* @andylockran
|
||||
@ -201,6 +203,7 @@ homeassistant/components/http/* @home-assistant/core
|
||||
homeassistant/components/huawei_lte/* @scop @fphammerle
|
||||
homeassistant/components/huawei_router/* @abmantis
|
||||
homeassistant/components/hue/* @balloob @frenck
|
||||
homeassistant/components/huisbaasje/* @denniss17
|
||||
homeassistant/components/humidifier/* @home-assistant/core @Shulyaka
|
||||
homeassistant/components/hunterdouglas_powerview/* @bdraco
|
||||
homeassistant/components/hvv_departures/* @vigonotion
|
||||
@ -256,7 +259,7 @@ homeassistant/components/luci/* @mzdrale
|
||||
homeassistant/components/luftdaten/* @fabaff
|
||||
homeassistant/components/lupusec/* @majuss
|
||||
homeassistant/components/lutron/* @JonGilmore
|
||||
homeassistant/components/lutron_caseta/* @swails
|
||||
homeassistant/components/lutron_caseta/* @swails @bdraco
|
||||
homeassistant/components/mastodon/* @fabaff
|
||||
homeassistant/components/matrix/* @tinloaf
|
||||
homeassistant/components/mcp23017/* @jardiamj
|
||||
@ -289,10 +292,10 @@ homeassistant/components/neato/* @dshokouhi @Santobert
|
||||
homeassistant/components/nederlandse_spoorwegen/* @YarmoM
|
||||
homeassistant/components/nello/* @pschmitt
|
||||
homeassistant/components/ness_alarm/* @nickw444
|
||||
homeassistant/components/nest/* @awarecan @allenporter
|
||||
homeassistant/components/nest/* @allenporter
|
||||
homeassistant/components/netatmo/* @cgtobi
|
||||
homeassistant/components/netdata/* @fabaff
|
||||
homeassistant/components/nexia/* @ryannazaretian @bdraco
|
||||
homeassistant/components/nexia/* @bdraco
|
||||
homeassistant/components/nextbus/* @vividboarder
|
||||
homeassistant/components/nextcloud/* @meichthys
|
||||
homeassistant/components/nightscout/* @marciogranzotto
|
||||
@ -318,6 +321,7 @@ homeassistant/components/ohmconnect/* @robbiet480
|
||||
homeassistant/components/ombi/* @larssont
|
||||
homeassistant/components/omnilogic/* @oliver84 @djtimca @gentoosu
|
||||
homeassistant/components/onboarding/* @home-assistant/core
|
||||
homeassistant/components/ondilo_ico/* @JeromeHXP
|
||||
homeassistant/components/onewire/* @garbled1 @epenet
|
||||
homeassistant/components/onvif/* @hunterjm
|
||||
homeassistant/components/openerz/* @misialq
|
||||
@ -351,7 +355,6 @@ homeassistant/components/progettihwsw/* @ardaseremet
|
||||
homeassistant/components/prometheus/* @knyar
|
||||
homeassistant/components/proxmoxve/* @k4ds3 @jhollowe
|
||||
homeassistant/components/ps4/* @ktnrg45
|
||||
homeassistant/components/ptvsd/* @swamp-ig
|
||||
homeassistant/components/push/* @dgomes
|
||||
homeassistant/components/pvoutput/* @fabaff
|
||||
homeassistant/components/pvpc_hourly_pricing/* @azogue
|
||||
@ -362,6 +365,7 @@ homeassistant/components/quantum_gateway/* @cisasteelersfan
|
||||
homeassistant/components/qvr_pro/* @oblogic7
|
||||
homeassistant/components/qwikswitch/* @kellerza
|
||||
homeassistant/components/rachio/* @bdraco
|
||||
homeassistant/components/radiotherm/* @vinnyfuria
|
||||
homeassistant/components/rainbird/* @konikvranik
|
||||
homeassistant/components/raincloud/* @vanstinator
|
||||
homeassistant/components/rainforest_eagle/* @gtdiehl @jcalbert
|
||||
@ -396,7 +400,7 @@ homeassistant/components/seven_segments/* @fabaff
|
||||
homeassistant/components/seventeentrack/* @bachya
|
||||
homeassistant/components/sharkiq/* @ajmarks
|
||||
homeassistant/components/shell_command/* @home-assistant/core
|
||||
homeassistant/components/shelly/* @balloob @bieniu @thecode
|
||||
homeassistant/components/shelly/* @balloob @bieniu @thecode @chemelli74
|
||||
homeassistant/components/shiftr/* @fabaff
|
||||
homeassistant/components/shodan/* @fabaff
|
||||
homeassistant/components/sighthound/* @robmarkcole
|
||||
@ -420,6 +424,7 @@ homeassistant/components/solarlog/* @Ernst79
|
||||
homeassistant/components/solax/* @squishykid
|
||||
homeassistant/components/soma/* @ratsept
|
||||
homeassistant/components/somfy/* @tetienne
|
||||
homeassistant/components/somfy_mylink/* @bdraco
|
||||
homeassistant/components/sonarr/* @ctalkington
|
||||
homeassistant/components/songpal/* @rytilahti @shenxn
|
||||
homeassistant/components/sonos/* @cgtobi
|
||||
@ -535,6 +540,7 @@ homeassistant/components/zodiac/* @JulienTant
|
||||
homeassistant/components/zone/* @home-assistant/core
|
||||
homeassistant/components/zoneminder/* @rohankapoorcom
|
||||
homeassistant/components/zwave/* @home-assistant/z-wave
|
||||
homeassistant/components/zwave_js/* @home-assistant/z-wave
|
||||
|
||||
# Individual files
|
||||
homeassistant/components/demo/weather @fabaff
|
||||
|
@ -1,8 +1,9 @@
|
||||
ARG BUILD_FROM
|
||||
FROM ${BUILD_FROM}
|
||||
|
||||
# Synchronize with homeassistant/core.py:async_stop
|
||||
ENV \
|
||||
S6_SERVICES_GRACETIME=60000
|
||||
S6_SERVICES_GRACETIME=220000
|
||||
|
||||
WORKDIR /usr/src
|
||||
|
||||
|
@ -14,8 +14,6 @@ pr:
|
||||
|
||||
resources:
|
||||
containers:
|
||||
- container: 37
|
||||
image: homeassistant/ci-azure:3.7
|
||||
- container: 38
|
||||
image: homeassistant/ci-azure:3.8
|
||||
repositories:
|
||||
@ -25,7 +23,7 @@ resources:
|
||||
endpoint: "home-assistant"
|
||||
variables:
|
||||
- name: PythonMain
|
||||
value: "37"
|
||||
value: "38"
|
||||
- name: versionHadolint
|
||||
value: "v1.17.6"
|
||||
|
||||
@ -150,8 +148,6 @@ stages:
|
||||
strategy:
|
||||
maxParallel: 3
|
||||
matrix:
|
||||
Python37:
|
||||
python.container: "37"
|
||||
Python38:
|
||||
python.container: "38"
|
||||
container: $[ variables['python.container'] ]
|
||||
|
@ -60,9 +60,9 @@ stages:
|
||||
vmImage: 'ubuntu-latest'
|
||||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
displayName: 'Use Python 3.7'
|
||||
displayName: 'Use Python 3.8'
|
||||
inputs:
|
||||
versionSpec: '3.7'
|
||||
versionSpec: '3.8'
|
||||
- script: pip install twine wheel
|
||||
displayName: 'Install tools'
|
||||
- script: python setup.py sdist bdist_wheel
|
||||
|
@ -30,9 +30,9 @@ jobs:
|
||||
vmImage: 'ubuntu-latest'
|
||||
steps:
|
||||
- task: UsePythonVersion@0
|
||||
displayName: 'Use Python 3.7'
|
||||
displayName: 'Use Python 3.8'
|
||||
inputs:
|
||||
versionSpec: '3.7'
|
||||
versionSpec: '3.8'
|
||||
- script: |
|
||||
export LOKALISE_TOKEN="$(lokaliseToken)"
|
||||
export AZURE_BRANCH="$(Build.SourceBranchName)"
|
||||
|
10
build.json
10
build.json
@ -1,11 +1,11 @@
|
||||
{
|
||||
"image": "homeassistant/{arch}-homeassistant",
|
||||
"build_from": {
|
||||
"aarch64": "homeassistant/aarch64-homeassistant-base:2021.01.0",
|
||||
"armhf": "homeassistant/armhf-homeassistant-base:2021.01.0",
|
||||
"armv7": "homeassistant/armv7-homeassistant-base:2021.01.0",
|
||||
"amd64": "homeassistant/amd64-homeassistant-base:2021.01.0",
|
||||
"i386": "homeassistant/i386-homeassistant-base:2021.01.0"
|
||||
"aarch64": "homeassistant/aarch64-homeassistant-base:2021.02.0",
|
||||
"armhf": "homeassistant/armhf-homeassistant-base:2021.02.0",
|
||||
"armv7": "homeassistant/armv7-homeassistant-base:2021.02.0",
|
||||
"amd64": "homeassistant/amd64-homeassistant-base:2021.02.0",
|
||||
"i386": "homeassistant/i386-homeassistant-base:2021.02.0"
|
||||
},
|
||||
"labels": {
|
||||
"io.hass.type": "core"
|
||||
|
@ -48,7 +48,7 @@ COOLDOWN_TIME = 60
|
||||
|
||||
MAX_LOAD_CONCURRENTLY = 6
|
||||
|
||||
DEBUGGER_INTEGRATIONS = {"debugpy", "ptvsd"}
|
||||
DEBUGGER_INTEGRATIONS = {"debugpy"}
|
||||
CORE_INTEGRATIONS = ("homeassistant", "persistent_notification")
|
||||
LOGGING_INTEGRATIONS = {
|
||||
# Set log levels
|
||||
@ -307,12 +307,10 @@ def async_enable_logging(
|
||||
sys.excepthook = lambda *args: logging.getLogger(None).exception(
|
||||
"Uncaught exception", exc_info=args # type: ignore
|
||||
)
|
||||
|
||||
if sys.version_info[:2] >= (3, 8):
|
||||
threading.excepthook = lambda args: logging.getLogger(None).exception(
|
||||
"Uncaught thread exception",
|
||||
exc_info=(args.exc_type, args.exc_value, args.exc_traceback),
|
||||
)
|
||||
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]
|
||||
)
|
||||
|
||||
# Log errors to a file if we have write access to file or config dir
|
||||
if log_file is None:
|
||||
@ -383,7 +381,7 @@ def _get_domains(hass: core.HomeAssistant, config: Dict[str, Any]) -> Set[str]:
|
||||
|
||||
|
||||
async def _async_log_pending_setups(
|
||||
domains: Set[str], setup_started: Dict[str, datetime]
|
||||
hass: core.HomeAssistant, domains: Set[str], setup_started: Dict[str, datetime]
|
||||
) -> None:
|
||||
"""Periodic log of setups that are pending for longer than LOG_SLOW_STARTUP_INTERVAL."""
|
||||
while True:
|
||||
@ -395,6 +393,7 @@ async def _async_log_pending_setups(
|
||||
"Waiting on integrations to complete setup: %s",
|
||||
", ".join(remaining),
|
||||
)
|
||||
_LOGGER.debug("Running timeout Zones: %s", hass.timeout.zones)
|
||||
|
||||
|
||||
async def async_setup_multi_components(
|
||||
@ -408,7 +407,9 @@ async def async_setup_multi_components(
|
||||
domain: hass.async_create_task(async_setup_component(hass, domain, config))
|
||||
for domain in domains
|
||||
}
|
||||
log_task = asyncio.create_task(_async_log_pending_setups(domains, setup_started))
|
||||
log_task = asyncio.create_task(
|
||||
_async_log_pending_setups(hass, domains, setup_started)
|
||||
)
|
||||
await asyncio.wait(futures.values())
|
||||
log_task.cancel()
|
||||
errors = [domain for domain in domains if futures[domain].exception()]
|
||||
|
@ -2,7 +2,7 @@
|
||||
"config": {
|
||||
"abort": {
|
||||
"reauth_successful": "Die erneute Authentifizierung war erfolgreich",
|
||||
"single_instance_allowed": "Es ist nur eine einzige Konfiguration von Abode erlaubt."
|
||||
"single_instance_allowed": "Bereits konfiguriert. Nur eine einzige Konfiguration m\u00f6glich."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Verbindung fehlgeschlagen",
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"reauth_successful": "La reautenticaci\u00f3n fue exitosa",
|
||||
"reauth_successful": "La reautenticaci\u00f3n se realiz\u00f3 correctamente",
|
||||
"single_instance_allowed": "Ya est\u00e1 configurado. Solo es posible una \u00fanica configuraci\u00f3n."
|
||||
},
|
||||
"error": {
|
||||
@ -19,7 +19,7 @@
|
||||
"reauth_confirm": {
|
||||
"data": {
|
||||
"password": "Contrase\u00f1a",
|
||||
"username": "Correo electronico"
|
||||
"username": "Correo electr\u00f3nico"
|
||||
},
|
||||
"title": "Rellene su informaci\u00f3n de inicio de sesi\u00f3n de Abode"
|
||||
},
|
||||
|
@ -1,17 +1,32 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Une seule configuration d'Abode est autoris\u00e9e."
|
||||
"reauth_successful": "La r\u00e9-authentification a r\u00e9ussi",
|
||||
"single_instance_allowed": "D\u00e9ja configur\u00e9. Une seule configuration possible."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "\u00c9chec de connexion",
|
||||
"invalid_auth": "Authentification invalide"
|
||||
"invalid_auth": "Authentification invalide",
|
||||
"invalid_mfa_code": "Code MFA non valide"
|
||||
},
|
||||
"step": {
|
||||
"mfa": {
|
||||
"data": {
|
||||
"mfa_code": "Code MFA (6 chiffres)"
|
||||
},
|
||||
"title": "Entrez votre code MFA pour Abode"
|
||||
},
|
||||
"reauth_confirm": {
|
||||
"data": {
|
||||
"password": "Mot de passe",
|
||||
"username": "Email"
|
||||
},
|
||||
"title": "Remplissez vos informations de connexion Abode"
|
||||
},
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Mot de passe",
|
||||
"username": "Adresse e-mail"
|
||||
"username": "Email"
|
||||
},
|
||||
"title": "Remplissez vos informations de connexion Abode"
|
||||
}
|
||||
|
34
homeassistant/components/abode/translations/tr.json
Normal file
34
homeassistant/components/abode/translations/tr.json
Normal file
@ -0,0 +1,34 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"reauth_successful": "Yeniden kimlik do\u011frulama ba\u015far\u0131l\u0131 oldu",
|
||||
"single_instance_allowed": "Zaten yap\u0131land\u0131r\u0131lm\u0131\u015f. Yaln\u0131zca tek bir konfig\u00fcrasyon m\u00fcmk\u00fcnd\u00fcr."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Ba\u011flanma hatas\u0131",
|
||||
"invalid_auth": "Ge\u00e7ersiz kimlik do\u011frulama",
|
||||
"invalid_mfa_code": "Ge\u00e7ersiz MFA kodu"
|
||||
},
|
||||
"step": {
|
||||
"mfa": {
|
||||
"data": {
|
||||
"mfa_code": "MFA kodu (6 basamakl\u0131)"
|
||||
},
|
||||
"title": "Abode i\u00e7in MFA kodunuzu girin"
|
||||
},
|
||||
"reauth_confirm": {
|
||||
"data": {
|
||||
"password": "Parola",
|
||||
"username": "E-posta"
|
||||
},
|
||||
"title": "Abode giri\u015f bilgilerinizi doldurun"
|
||||
},
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Parola",
|
||||
"username": "E-posta"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
35
homeassistant/components/abode/translations/uk.json
Normal file
35
homeassistant/components/abode/translations/uk.json
Normal file
@ -0,0 +1,35 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"reauth_successful": "\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u0430 \u0430\u0432\u0442\u0435\u043d\u0442\u0438\u0444\u0456\u043a\u0430\u0446\u0456\u044f \u043f\u0440\u043e\u0439\u0448\u043b\u0430 \u0443\u0441\u043f\u0456\u0448\u043d\u043e",
|
||||
"single_instance_allowed": "\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0432\u0436\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e. \u041c\u043e\u0436\u043d\u0430 \u0434\u043e\u0434\u0430\u0442\u0438 \u043b\u0438\u0448\u0435 \u043e\u0434\u043d\u0443 \u043a\u043e\u043d\u0444\u0456\u0433\u0443\u0440\u0430\u0446\u0456\u044e."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "\u041d\u0435 \u0432\u0434\u0430\u043b\u043e\u0441\u044f \u043f\u0456\u0434'\u0454\u0434\u043d\u0430\u0442\u0438\u0441\u044f",
|
||||
"invalid_auth": "\u041d\u0435\u0432\u0456\u0440\u043d\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0456\u043a\u0430\u0446\u0456\u044f.",
|
||||
"invalid_mfa_code": "\u041d\u0435\u0434\u0456\u0439\u0441\u043d\u0438\u0439 \u043a\u043e\u0434 MFA."
|
||||
},
|
||||
"step": {
|
||||
"mfa": {
|
||||
"data": {
|
||||
"mfa_code": "\u041a\u043e\u0434 MFA (6 \u0446\u0438\u0444\u0440)"
|
||||
},
|
||||
"title": "\u0412\u0432\u0435\u0434\u0456\u0442\u044c \u043a\u043e\u0434 MFA \u0434\u043b\u044f Abode"
|
||||
},
|
||||
"reauth_confirm": {
|
||||
"data": {
|
||||
"password": "\u041f\u0430\u0440\u043e\u043b\u044c",
|
||||
"username": "\u0410\u0434\u0440\u0435\u0441\u0430 \u0435\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0457 \u043f\u043e\u0448\u0442\u0438"
|
||||
},
|
||||
"title": "Abode"
|
||||
},
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "\u041f\u0430\u0440\u043e\u043b\u044c",
|
||||
"username": "\u0410\u0434\u0440\u0435\u0441\u0430 \u0435\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0457 \u043f\u043e\u0448\u0442\u0438"
|
||||
},
|
||||
"title": "Abode"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -100,13 +100,13 @@ class AccuWeatherDataUpdateCoordinator(DataUpdateCoordinator):
|
||||
self.accuweather = AccuWeather(api_key, session, location_key=self.location_key)
|
||||
|
||||
# Enabling the forecast download increases the number of requests per data
|
||||
# update, we use 32 minutes for current condition only and 64 minutes for
|
||||
# update, we use 40 minutes for current condition only and 80 minutes for
|
||||
# current condition and forecast as update interval to not exceed allowed number
|
||||
# of requests. We have 50 requests allowed per day, so we use 45 and leave 5 as
|
||||
# of requests. We have 50 requests allowed per day, so we use 36 and leave 14 as
|
||||
# a reserve for restarting HA.
|
||||
update_interval = (
|
||||
timedelta(minutes=64) if self.forecast else timedelta(minutes=32)
|
||||
)
|
||||
update_interval = timedelta(minutes=40)
|
||||
if self.forecast:
|
||||
update_interval *= 2
|
||||
_LOGGER.debug("Data will be update every %s", update_interval)
|
||||
|
||||
super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=update_interval)
|
||||
|
@ -52,12 +52,12 @@ CONDITION_CLASSES = {
|
||||
ATTR_CONDITION_HAIL: [25],
|
||||
ATTR_CONDITION_LIGHTNING: [15],
|
||||
ATTR_CONDITION_LIGHTNING_RAINY: [16, 17, 41, 42],
|
||||
ATTR_CONDITION_PARTLYCLOUDY: [4, 6, 35, 36],
|
||||
ATTR_CONDITION_PARTLYCLOUDY: [3, 4, 6, 35, 36],
|
||||
ATTR_CONDITION_POURING: [18],
|
||||
ATTR_CONDITION_RAINY: [12, 13, 14, 26, 39, 40],
|
||||
ATTR_CONDITION_SNOWY: [19, 20, 21, 22, 23, 43, 44],
|
||||
ATTR_CONDITION_SNOWY_RAINY: [29],
|
||||
ATTR_CONDITION_SUNNY: [1, 2, 3, 5],
|
||||
ATTR_CONDITION_SUNNY: [1, 2, 5],
|
||||
ATTR_CONDITION_WINDY: [32],
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
"step": {
|
||||
"user": {
|
||||
"title": "AccuWeather Options",
|
||||
"description": "Due to the limitations of the free version of the AccuWeather API key, when you enable weather forecast, data updates will be performed every 64 minutes instead of every 32 minutes.",
|
||||
"description": "Due to the limitations of the free version of the AccuWeather API key, when you enable weather forecast, data updates will be performed every 80 minutes instead of every 40 minutes.",
|
||||
"data": {
|
||||
"forecast": "Weather forecast"
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
"data": {
|
||||
"forecast": "Previsi\u00f3 meteorol\u00f2gica"
|
||||
},
|
||||
"description": "Per culpa de les limitacions de la versi\u00f3 gratu\u00efta l'API d'AccuWeather, quan habilitis la previsi\u00f3 meteorol\u00f2gica, les actualitzacions es realitzaran cada 64 minuts en comptes de 32.",
|
||||
"description": "Per culpa de les limitacions de la versi\u00f3 gratu\u00efta l'API d'AccuWeather, quan habilitis la previsi\u00f3 meteorol\u00f2gica, les actualitzacions de dades es faran cada 80 minuts en comptes de cada 40.",
|
||||
"title": "Opcions d'AccuWeather"
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
"data": {
|
||||
"forecast": "P\u0159edpov\u011b\u010f po\u010das\u00ed"
|
||||
},
|
||||
"description": "Kdy\u017e povol\u00edte p\u0159edpov\u011b\u010f po\u010das\u00ed, budou aktualizace dat prov\u00e1d\u011bny ka\u017ed\u00fdch 64 minut nam\u00edsto 32 minut z d\u016fvodu omezen\u00ed bezplatn\u00e9 verze AccuWeather.",
|
||||
"description": "Kdy\u017e povol\u00edte p\u0159edpov\u011b\u010f po\u010das\u00ed, budou aktualizace dat prov\u00e1d\u011bny ka\u017ed\u00fdch 80 minut nam\u00edsto 40 minut z d\u016fvodu omezen\u00ed bezplatn\u00e9 verze AccuWeather.",
|
||||
"title": "Mo\u017enosti AccuWeather"
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,16 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Bereits konfiguriert. Nur eine einzige Konfiguration m\u00f6glich."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Verbindungsfehler"
|
||||
"cannot_connect": "Verbindung fehlgeschlagen",
|
||||
"invalid_api_key": "Ung\u00fcltiger API-Schl\u00fcssel"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"api_key": "API-Schl\u00fcssel",
|
||||
"latitude": "Breitengrad",
|
||||
"longitude": "L\u00e4ngengrad",
|
||||
"name": "Name"
|
||||
@ -25,7 +30,7 @@
|
||||
},
|
||||
"system_health": {
|
||||
"info": {
|
||||
"can_reach_server": "AccuWeather Server erreichen",
|
||||
"can_reach_server": "AccuWeather-Server erreichen",
|
||||
"remaining_requests": "Verbleibende erlaubte Anfragen"
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
"data": {
|
||||
"forecast": "Weather forecast"
|
||||
},
|
||||
"description": "Due to the limitations of the free version of the AccuWeather API key, when you enable weather forecast, data updates will be performed every 64 minutes instead of every 32 minutes.",
|
||||
"description": "Due to the limitations of the free version of the AccuWeather API key, when you enable weather forecast, data updates will be performed every 80 minutes instead of every 40 minutes.",
|
||||
"title": "AccuWeather Options"
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
"data": {
|
||||
"forecast": "Ilmateade"
|
||||
},
|
||||
"description": "AccuWeather API tasuta versioonis toimub ilmaennustuse lubamisel andmete v\u00e4rskendamine iga 32 minuti asemel iga 64 minuti j\u00e4rel.",
|
||||
"description": "AccuWeather API tasuta versioonis toimub ilmaennustuse lubamisel andmete v\u00e4rskendamine iga 80 minuti j\u00e4rel (muidu 40 minutit).",
|
||||
"title": "AccuWeatheri valikud"
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,8 @@
|
||||
},
|
||||
"system_health": {
|
||||
"info": {
|
||||
"can_reach_server": "Acc\u00e8s au serveur AccuWeather"
|
||||
"can_reach_server": "Acc\u00e8s au serveur AccuWeather",
|
||||
"remaining_requests": "Demandes restantes autoris\u00e9es"
|
||||
}
|
||||
}
|
||||
}
|
@ -27,7 +27,7 @@
|
||||
"data": {
|
||||
"forecast": "Previsioni meteo"
|
||||
},
|
||||
"description": "A causa delle limitazioni della versione gratuita della chiave API AccuWeather, quando si abilitano le previsioni del tempo, gli aggiornamenti dei dati verranno eseguiti ogni 64 minuti invece che ogni 32 minuti.",
|
||||
"description": "A causa delle limitazioni della versione gratuita della chiave API AccuWeather, quando si abilitano le previsioni del tempo, gli aggiornamenti dei dati verranno eseguiti ogni 80 minuti invece che ogni 40.",
|
||||
"title": "Opzioni AccuWeather"
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
"data": {
|
||||
"forecast": "V\u00e6rmelding"
|
||||
},
|
||||
"description": "P\u00e5 grunn av begrensningene i gratisversjonen av AccuWeather API-n\u00f8kkelen, n\u00e5r du aktiverer v\u00e6rmelding, vil dataoppdateringer bli utf\u00f8rt hvert 64. minutt i stedet for hvert 32. minutt.",
|
||||
"description": "P\u00e5 grunn av begrensningene i den gratis versjonen av AccuWeather API-n\u00f8kkelen, vil dataoppdateringer utf\u00f8res hvert 80. minutt i stedet for hvert 40. minutt n\u00e5r du aktiverer v\u00e6rmelding.",
|
||||
"title": "AccuWeather-alternativer"
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
"data": {
|
||||
"forecast": "Prognoza pogody"
|
||||
},
|
||||
"description": "Ze wzgl\u0119du na ograniczenia darmowej wersji klucza API AccuWeather po w\u0142\u0105czeniu prognozy pogody aktualizacje danych b\u0119d\u0105 wykonywane co 64 minuty zamiast co 32 minuty.",
|
||||
"description": "Ze wzgl\u0119du na ograniczenia darmowej wersji klucza API AccuWeather po w\u0142\u0105czeniu prognozy pogody aktualizacje danych b\u0119d\u0105 wykonywane co 80 minut zamiast co 40 minut.",
|
||||
"title": "Opcje AccuWeather"
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,7 @@
|
||||
"data": {
|
||||
"forecast": "\u041f\u0440\u043e\u0433\u043d\u043e\u0437 \u043f\u043e\u0433\u043e\u0434\u044b"
|
||||
},
|
||||
"description": "\u0412 \u0441\u0432\u044f\u0437\u0438 \u0441 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f\u043c\u0438 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u043a\u043b\u044e\u0447\u0430 API AccuWeather, \u043f\u0440\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438 \u043f\u0440\u043e\u0433\u043d\u043e\u0437\u0430 \u043f\u043e\u0433\u043e\u0434\u044b \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c \u043a\u0430\u0436\u0434\u044b\u0435 64 \u043c\u0438\u043d\u0443\u0442\u044b, \u0430 \u043d\u0435 \u043a\u0430\u0436\u0434\u044b\u0435 32 \u043c\u0438\u043d\u0443\u0442\u044b.",
|
||||
"description": "\u0412 \u0441\u0432\u044f\u0437\u0438 \u0441 \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u044f\u043c\u0438 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u043a\u043b\u044e\u0447\u0430 API AccuWeather, \u043f\u0440\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438 \u043f\u0440\u043e\u0433\u043d\u043e\u0437\u0430 \u043f\u043e\u0433\u043e\u0434\u044b \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0445 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c \u043a\u0430\u0436\u0434\u044b\u0435 80 \u043c\u0438\u043d\u0443\u0442, \u0430 \u043d\u0435 \u043a\u0430\u0436\u0434\u044b\u0435 40 \u043c\u0438\u043d\u0443\u0442.",
|
||||
"title": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 AccuWeather"
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,9 @@
|
||||
{
|
||||
"state": {
|
||||
"accuweather__pressure_tendency": {
|
||||
"falling": "\u0417\u043d\u0438\u0436\u0435\u043d\u043d\u044f",
|
||||
"rising": "\u0417\u0440\u043e\u0441\u0442\u0430\u043d\u043d\u044f",
|
||||
"steady": "\u0421\u0442\u0430\u0431\u0456\u043b\u044c\u043d\u0438\u0439"
|
||||
}
|
||||
}
|
||||
}
|
38
homeassistant/components/accuweather/translations/tr.json
Normal file
38
homeassistant/components/accuweather/translations/tr.json
Normal file
@ -0,0 +1,38 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Zaten yap\u0131land\u0131r\u0131lm\u0131\u015f. Yaln\u0131zca tek bir konfig\u00fcrasyon m\u00fcmk\u00fcnd\u00fcr."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Ba\u011flanma hatas\u0131",
|
||||
"invalid_api_key": "Ge\u00e7ersiz API anahtar\u0131"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"api_key": "API Anahtar\u0131",
|
||||
"latitude": "Enlem",
|
||||
"longitude": "Boylam",
|
||||
"name": "Ad"
|
||||
},
|
||||
"title": "AccuWeather"
|
||||
}
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"forecast": "Hava Durumu tahmini"
|
||||
},
|
||||
"title": "AccuWeather Se\u00e7enekleri"
|
||||
}
|
||||
}
|
||||
},
|
||||
"system_health": {
|
||||
"info": {
|
||||
"can_reach_server": "AccuWeather sunucusuna ula\u015f\u0131n",
|
||||
"remaining_requests": "Kalan izin verilen istekler"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,15 +1,22 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0432\u0436\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e. \u041c\u043e\u0436\u043d\u0430 \u0434\u043e\u0434\u0430\u0442\u0438 \u043b\u0438\u0448\u0435 \u043e\u0434\u043d\u0443 \u043a\u043e\u043d\u0444\u0456\u0433\u0443\u0440\u0430\u0446\u0456\u044e."
|
||||
},
|
||||
"error": {
|
||||
"invalid_api_key": "\u0425\u0438\u0431\u043d\u0438\u0439 \u043a\u043b\u044e\u0447 API"
|
||||
"cannot_connect": "\u041d\u0435 \u0432\u0434\u0430\u043b\u043e\u0441\u044f \u043f\u0456\u0434'\u0454\u0434\u043d\u0430\u0442\u0438\u0441\u044f",
|
||||
"invalid_api_key": "\u0425\u0438\u0431\u043d\u0438\u0439 \u043a\u043b\u044e\u0447 API",
|
||||
"requests_exceeded": "\u041f\u0435\u0440\u0435\u0432\u0438\u0449\u0435\u043d\u043e \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u0443 \u043a\u0456\u043b\u044c\u043a\u0456\u0441\u0442\u044c \u0437\u0430\u043f\u0438\u0442\u0456\u0432 \u0434\u043e API Accuweather. \u041d\u0435\u043e\u0431\u0445\u0456\u0434\u043d\u043e \u043f\u043e\u0447\u0435\u043a\u0430\u0442\u0438 \u0430\u0431\u043e \u0437\u043c\u0456\u043d\u0438\u0442\u0438 \u043a\u043b\u044e\u0447 API."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"api_key": "\u041a\u043b\u044e\u0447 API",
|
||||
"latitude": "\u0428\u0438\u0440\u043e\u0442\u0430",
|
||||
"longitude": "\u0414\u043e\u0432\u0433\u043e\u0442\u0430",
|
||||
"name": "\u041d\u0430\u0437\u0432\u0430 \u0456\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0456\u0457"
|
||||
"name": "\u041d\u0430\u0437\u0432\u0430"
|
||||
},
|
||||
"description": "\u041e\u0437\u043d\u0430\u0439\u043e\u043c\u0442\u0435\u0441\u044f \u0437 \u0456\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0456\u044f\u043c\u0438, \u044f\u043a\u0449\u043e \u0412\u0430\u043c \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u0430 \u0434\u043e\u043f\u043e\u043c\u043e\u0433\u0430 \u0437 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f\u043c:\n https://www.home-assistant.io/integrations/accuweather/ \n\n\u0417\u0430 \u0437\u0430\u043c\u043e\u0432\u0447\u0443\u0432\u0430\u043d\u043d\u044f\u043c \u0434\u0435\u044f\u043a\u0456 \u0441\u0435\u043d\u0441\u043e\u0440\u0438 \u043f\u0440\u0438\u0445\u043e\u0432\u0430\u043d\u0456 \u0456 \u0432\u0456\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u043f\u0440\u043e\u0433\u043d\u043e\u0437 \u043f\u043e\u0433\u043e\u0434\u0438. \u0412\u0438 \u043c\u043e\u0436\u0435\u0442\u0435 \u0430\u043a\u0442\u0438\u0432\u0443\u0432\u0430\u0442\u0438 \u0432\u0456\u0434\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u043d\u044f \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u0438\u0445 \u0441\u0435\u043d\u0441\u043e\u0440\u0456\u0432 \u0432 \u0440\u0435\u0454\u0441\u0442\u0440\u0456 \u043e\u0431'\u0454\u043a\u0442\u0456\u0432 \u0456 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u0438 \u043f\u0440\u043e\u0433\u043d\u043e\u0437 \u043f\u043e\u0433\u043e\u0434\u0438 \u0432 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f\u0445 \u0456\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0456\u0457.",
|
||||
"title": "AccuWeather"
|
||||
}
|
||||
}
|
||||
@ -19,8 +26,16 @@
|
||||
"user": {
|
||||
"data": {
|
||||
"forecast": "\u041f\u0440\u043e\u0433\u043d\u043e\u0437 \u043f\u043e\u0433\u043e\u0434\u0438"
|
||||
}
|
||||
},
|
||||
"description": "\u0423 \u0437\u0432'\u044f\u0437\u043a\u0443 \u0437 \u043e\u0431\u043c\u0435\u0436\u0435\u043d\u043d\u044f\u043c\u0438 \u0431\u0435\u0437\u043a\u043e\u0448\u0442\u043e\u0432\u043d\u043e\u0457 \u0432\u0435\u0440\u0441\u0456\u0457 \u043a\u043b\u044e\u0447\u0430 API AccuWeather, \u043f\u0440\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u0456 \u043f\u0440\u043e\u0433\u043d\u043e\u0437\u0443 \u043f\u043e\u0433\u043e\u0434\u0438 \u043e\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044f \u0434\u0430\u043d\u0438\u0445 \u0431\u0443\u0434\u0435 \u0432\u0456\u0434\u0431\u0443\u0432\u0430\u0442\u0438\u0441\u044f \u043a\u043e\u0436\u043d\u0456 64 \u0445\u0432\u0438\u043b\u0438\u043d\u0438, \u0430 \u043d\u0435 \u043a\u043e\u0436\u043d\u0456 32 \u0445\u0432\u0438\u043b\u0438\u043d\u0438.",
|
||||
"title": "\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f AccuWeather"
|
||||
}
|
||||
}
|
||||
},
|
||||
"system_health": {
|
||||
"info": {
|
||||
"can_reach_server": "\u0414\u043e\u0441\u0442\u0443\u043f \u0434\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 AccuWeather",
|
||||
"remaining_requests": "\u0417\u0430\u043f\u0438\u0442\u0456\u0432 \u0437\u0430\u043b\u0438\u0448\u0438\u043b\u043e\u0441\u044c"
|
||||
}
|
||||
}
|
||||
}
|
@ -27,7 +27,7 @@
|
||||
"data": {
|
||||
"forecast": "\u5929\u6c23\u9810\u5831"
|
||||
},
|
||||
"description": "\u7531\u65bc AccuWeather API \u5bc6\u9470\u514d\u8cbb\u7248\u672c\u9650\u5236\uff0c\u7576\u958b\u555f\u5929\u6c23\u9810\u5831\u6642\u3001\u6578\u64da\u6703\u6bcf 64 \u5206\u9418\u66f4\u65b0\u4e00\u6b21\uff0c\u800c\u975e 32 \u5206\u9418\u3002",
|
||||
"description": "\u7531\u65bc AccuWeather API \u5bc6\u9470\u514d\u8cbb\u7248\u672c\u9650\u5236\uff0c\u7576\u958b\u555f\u5929\u6c23\u9810\u5831\u6642\u3001\u6578\u64da\u6703\u6bcf 80 \u5206\u9418\u66f4\u65b0\u4e00\u6b21\uff0c\u800c\u975e 40 \u5206\u9418\u3002",
|
||||
"title": "AccuWeather \u9078\u9805"
|
||||
}
|
||||
}
|
||||
|
@ -26,9 +26,7 @@ class AcmedaBase(entity.Entity):
|
||||
ent_registry.async_remove(self.entity_id)
|
||||
|
||||
dev_registry = await get_dev_reg(self.hass)
|
||||
device = dev_registry.async_get_device(
|
||||
identifiers={(DOMAIN, self.unique_id)}, connections=set()
|
||||
)
|
||||
device = dev_registry.async_get_device(identifiers={(DOMAIN, self.unique_id)})
|
||||
if device is not None:
|
||||
dev_registry.async_update_device(
|
||||
device.id, remove_config_entry_id=self.registry_entry.config_entry_id
|
||||
|
@ -32,9 +32,7 @@ async def update_devices(hass, config_entry, api):
|
||||
|
||||
for api_item in api.values():
|
||||
# Update Device name
|
||||
device = dev_registry.async_get_device(
|
||||
identifiers={(DOMAIN, api_item.id)}, connections=set()
|
||||
)
|
||||
device = dev_registry.async_get_device(identifiers={(DOMAIN, api_item.id)})
|
||||
if device is not None:
|
||||
dev_registry.async_update_device(
|
||||
device.id,
|
||||
|
@ -1,11 +1,14 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"no_devices_found": "Keine Ger\u00e4te im Netzwerk gefunden"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"id": "Host-ID"
|
||||
},
|
||||
"title": "W\u00e4hlen Sie einen Hub zum Hinzuf\u00fcgen aus"
|
||||
"title": "W\u00e4hle einen Hub zum Hinzuf\u00fcgen aus"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
11
homeassistant/components/acmeda/translations/tr.json
Normal file
11
homeassistant/components/acmeda/translations/tr.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"config": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"id": "Ana bilgisayar kimli\u011fi"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
15
homeassistant/components/acmeda/translations/uk.json
Normal file
15
homeassistant/components/acmeda/translations/uk.json
Normal file
@ -0,0 +1,15 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"no_devices_found": "\u041f\u0440\u0438\u0441\u0442\u0440\u043e\u0457 \u043d\u0435 \u0437\u043d\u0430\u0439\u0434\u0435\u043d\u0456 \u0432 \u043c\u0435\u0440\u0435\u0436\u0456."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"id": "\u0406\u0434\u0435\u043d\u0442\u0438\u0444\u0456\u043a\u0430\u0442\u043e\u0440 \u0445\u043e\u0441\u0442\u0430"
|
||||
},
|
||||
"title": "\u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u0445\u0430\u0431, \u044f\u043a\u0438\u0439 \u043f\u043e\u0442\u0440\u0456\u0431\u043d\u043e \u0434\u043e\u0434\u0430\u0442\u0438"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,10 +2,10 @@
|
||||
"config": {
|
||||
"abort": {
|
||||
"existing_instance_updated": "Bestehende Konfiguration wurde aktualisiert.",
|
||||
"single_instance_allowed": "Es ist nur eine einzige Konfiguration von AdGuard Home zul\u00e4ssig."
|
||||
"single_instance_allowed": "Bereits konfiguriert. Nur eine einzige Konfiguration m\u00f6glich."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Verbindungsfehler"
|
||||
"cannot_connect": "Verbindung fehlgeschlagen"
|
||||
},
|
||||
"step": {
|
||||
"hassio_confirm": {
|
||||
@ -19,7 +19,7 @@
|
||||
"port": "Port",
|
||||
"ssl": "AdGuard Home verwendet ein SSL-Zertifikat",
|
||||
"username": "Benutzername",
|
||||
"verify_ssl": "AdGuard Home verwendet ein richtiges Zertifikat"
|
||||
"verify_ssl": "SSL-Zertifikat \u00fcberpr\u00fcfen"
|
||||
},
|
||||
"description": "Richte deine AdGuard Home-Instanz ein um sie zu \u00dcberwachen und zu Steuern."
|
||||
}
|
||||
|
@ -9,8 +9,8 @@
|
||||
},
|
||||
"step": {
|
||||
"hassio_confirm": {
|
||||
"description": "Vil du konfigurere Home Assistant til \u00e5 koble til AdGuard Hjem gitt av hass.io tillegget {addon}?",
|
||||
"title": "AdGuard Hjem via Hass.io tillegg"
|
||||
"description": "Vil du konfigurere Home Assistant til \u00e5 koble til AdGuard Home gitt av Hass.io-tillegg {addon}?",
|
||||
"title": "AdGuard Home via Hass.io-tillegg"
|
||||
},
|
||||
"user": {
|
||||
"data": {
|
||||
|
@ -9,8 +9,8 @@
|
||||
},
|
||||
"step": {
|
||||
"hassio_confirm": {
|
||||
"description": "\u0412\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a AdGuard Home (\u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0434\u043b\u044f Hass.io \"{addon}\")?",
|
||||
"title": "AdGuard Home (\u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0434\u043b\u044f Hass.io)"
|
||||
"description": "\u0412\u044b \u0443\u0432\u0435\u0440\u0435\u043d\u044b, \u0447\u0442\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043a AdGuard Home (\u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0434\u043b\u044f Home Assistant \"{addon}\")?",
|
||||
"title": "AdGuard Home (\u0434\u043e\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0434\u043b\u044f Home Assistant)"
|
||||
},
|
||||
"user": {
|
||||
"data": {
|
||||
|
20
homeassistant/components/adguard/translations/tr.json
Normal file
20
homeassistant/components/adguard/translations/tr.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Zaten yap\u0131land\u0131r\u0131lm\u0131\u015f. Yaln\u0131zca tek bir konfig\u00fcrasyon m\u00fcmk\u00fcnd\u00fcr."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Ba\u011flanma hatas\u0131"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"host": "Ana Bilgisayar",
|
||||
"password": "Parola",
|
||||
"port": "Port",
|
||||
"username": "Kullan\u0131c\u0131 Ad\u0131"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
28
homeassistant/components/adguard/translations/uk.json
Normal file
28
homeassistant/components/adguard/translations/uk.json
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"existing_instance_updated": "\u041a\u043e\u043d\u0444\u0456\u0433\u0443\u0440\u0430\u0446\u0456\u044f \u043e\u043d\u043e\u0432\u043b\u0435\u043d\u0430.",
|
||||
"single_instance_allowed": "\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0432\u0436\u0435 \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d\u043e. \u041c\u043e\u0436\u043d\u0430 \u0434\u043e\u0434\u0430\u0442\u0438 \u043b\u0438\u0448\u0435 \u043e\u0434\u043d\u0443 \u043a\u043e\u043d\u0444\u0456\u0433\u0443\u0440\u0430\u0446\u0456\u044e."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "\u041d\u0435 \u0432\u0434\u0430\u043b\u043e\u0441\u044f \u043f\u0456\u0434'\u0454\u0434\u043d\u0430\u0442\u0438\u0441\u044f"
|
||||
},
|
||||
"step": {
|
||||
"hassio_confirm": {
|
||||
"description": "\u0412\u0438 \u0432\u043f\u0435\u0432\u043d\u0435\u043d\u0456, \u0449\u043e \u0445\u043e\u0447\u0435\u0442\u0435 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u0442\u0438 \u043f\u0456\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044f \u0434\u043e AdGuard Home (\u0434\u043e\u0434\u0430\u0442\u043e\u043a \u0434\u043b\u044f Hass.io \"{addon}\")?",
|
||||
"title": "AdGuard Home (\u0434\u043e\u0434\u0430\u0442\u043e\u043a \u0434\u043b\u044f Hass.io)"
|
||||
},
|
||||
"user": {
|
||||
"data": {
|
||||
"host": "\u0425\u043e\u0441\u0442",
|
||||
"password": "\u041f\u0430\u0440\u043e\u043b\u044c",
|
||||
"port": "\u041f\u043e\u0440\u0442",
|
||||
"ssl": "\u0412\u0438\u043a\u043e\u0440\u0438\u0441\u0442\u043e\u0432\u0443\u0454\u0442\u044c\u0441\u044f \u0441\u0435\u0440\u0442\u0438\u0444\u0456\u043a\u0430\u0442 SSL",
|
||||
"username": "\u0406\u043c'\u044f \u043a\u043e\u0440\u0438\u0441\u0442\u0443\u0432\u0430\u0447\u0430",
|
||||
"verify_ssl": "\u041f\u0435\u0440\u0435\u0432\u0456\u0440\u043a\u0430 \u0441\u0435\u0440\u0442\u0438\u0444\u0456\u043a\u0430\u0442\u0430 SSL"
|
||||
},
|
||||
"description": "\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0439\u0442\u0435 Home Assistant \u0434\u043b\u044f \u043c\u043e\u043d\u0456\u0442\u043e\u0440\u0438\u043d\u0433\u0443 \u0456 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044e AdGuard Home."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,10 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Ger\u00e4t ist bereits konfiguriert"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Verbindungsfehler"
|
||||
"cannot_connect": "Verbindung fehlgeschlagen"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
|
19
homeassistant/components/advantage_air/translations/tr.json
Normal file
19
homeassistant/components/advantage_air/translations/tr.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Cihaz zaten yap\u0131land\u0131r\u0131lm\u0131\u015f"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Ba\u011flanma hatas\u0131"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"ip_address": "\u0130p Adresi",
|
||||
"port": "Port"
|
||||
},
|
||||
"title": "Ba\u011flan"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
20
homeassistant/components/advantage_air/translations/uk.json
Normal file
20
homeassistant/components/advantage_air/translations/uk.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "\u0426\u0435\u0439 \u043f\u0440\u0438\u0441\u0442\u0440\u0456\u0439 \u0432\u0436\u0435 \u0434\u043e\u0434\u0430\u043d\u043e \u0432 Home Assistant."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "\u041d\u0435 \u0432\u0434\u0430\u043b\u043e\u0441\u044f \u043f\u0456\u0434'\u0454\u0434\u043d\u0430\u0442\u0438\u0441\u044f"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"ip_address": "IP-\u0430\u0434\u0440\u0435\u0441\u0430",
|
||||
"port": "\u041f\u043e\u0440\u0442"
|
||||
},
|
||||
"description": "\u041f\u0456\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044f \u0434\u043e API \u0412\u0430\u0448\u043e\u0433\u043e \u043d\u0430\u0441\u0442\u0456\u043d\u043d\u043e\u0433\u043e \u043f\u043b\u0430\u043d\u0448\u0435\u0442\u0430 Advantage Air.",
|
||||
"title": "\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u043f\u0456\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044f"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -4,8 +4,8 @@
|
||||
"already_configured": "Ger\u00e4t ist bereits konfiguriert"
|
||||
},
|
||||
"error": {
|
||||
"already_in_progress": "Der Konfigurationsfluss f\u00fcr das Ger\u00e4t wird bereits ausgef\u00fchrt.",
|
||||
"cannot_connect": "Verbindungsfehler"
|
||||
"already_in_progress": "Der Konfigurationsablauf wird bereits ausgef\u00fchrt",
|
||||
"cannot_connect": "Verbindung fehlgeschlagen"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
|
20
homeassistant/components/agent_dvr/translations/tr.json
Normal file
20
homeassistant/components/agent_dvr/translations/tr.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Cihaz zaten yap\u0131land\u0131r\u0131lm\u0131\u015f"
|
||||
},
|
||||
"error": {
|
||||
"already_in_progress": "Yap\u0131land\u0131rma ak\u0131\u015f\u0131 zaten devam ediyor",
|
||||
"cannot_connect": "Ba\u011flanma hatas\u0131"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"host": "Ana Bilgisayar",
|
||||
"port": "Port"
|
||||
},
|
||||
"title": "Agent DVR'\u0131 kurun"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
20
homeassistant/components/agent_dvr/translations/uk.json
Normal file
20
homeassistant/components/agent_dvr/translations/uk.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "\u0426\u0435\u0439 \u043f\u0440\u0438\u0441\u0442\u0440\u0456\u0439 \u0432\u0436\u0435 \u0434\u043e\u0434\u0430\u043d\u043e \u0432 Home Assistant."
|
||||
},
|
||||
"error": {
|
||||
"already_in_progress": "\u041f\u0440\u043e\u0446\u0435\u0441 \u043d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0432\u0436\u0435 \u0442\u0440\u0438\u0432\u0430\u0454.",
|
||||
"cannot_connect": "\u041d\u0435 \u0432\u0434\u0430\u043b\u043e\u0441\u044f \u043f\u0456\u0434'\u0454\u0434\u043d\u0430\u0442\u0438\u0441\u044f"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"host": "\u0425\u043e\u0441\u0442",
|
||||
"port": "\u041f\u043e\u0440\u0442"
|
||||
},
|
||||
"title": "Agent DVR"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -20,6 +20,7 @@ from .const import (
|
||||
ATTR_API_CAQI,
|
||||
ATTR_API_CAQI_DESCRIPTION,
|
||||
ATTR_API_CAQI_LEVEL,
|
||||
CONF_USE_NEAREST,
|
||||
DOMAIN,
|
||||
MAX_REQUESTS_PER_DAY,
|
||||
NO_AIRLY_SENSORS,
|
||||
@ -53,6 +54,7 @@ async def async_setup_entry(hass, config_entry):
|
||||
api_key = config_entry.data[CONF_API_KEY]
|
||||
latitude = config_entry.data[CONF_LATITUDE]
|
||||
longitude = config_entry.data[CONF_LONGITUDE]
|
||||
use_nearest = config_entry.data.get(CONF_USE_NEAREST, False)
|
||||
|
||||
# For backwards compat, set unique ID
|
||||
if config_entry.unique_id is None:
|
||||
@ -67,7 +69,7 @@ async def async_setup_entry(hass, config_entry):
|
||||
)
|
||||
|
||||
coordinator = AirlyDataUpdateCoordinator(
|
||||
hass, websession, api_key, latitude, longitude, update_interval
|
||||
hass, websession, api_key, latitude, longitude, update_interval, use_nearest
|
||||
)
|
||||
await coordinator.async_refresh()
|
||||
|
||||
@ -107,21 +109,36 @@ async def async_unload_entry(hass, config_entry):
|
||||
class AirlyDataUpdateCoordinator(DataUpdateCoordinator):
|
||||
"""Define an object to hold Airly data."""
|
||||
|
||||
def __init__(self, hass, session, api_key, latitude, longitude, update_interval):
|
||||
def __init__(
|
||||
self,
|
||||
hass,
|
||||
session,
|
||||
api_key,
|
||||
latitude,
|
||||
longitude,
|
||||
update_interval,
|
||||
use_nearest,
|
||||
):
|
||||
"""Initialize."""
|
||||
self.latitude = latitude
|
||||
self.longitude = longitude
|
||||
self.airly = Airly(api_key, session)
|
||||
self.use_nearest = use_nearest
|
||||
|
||||
super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=update_interval)
|
||||
|
||||
async def _async_update_data(self):
|
||||
"""Update data via library."""
|
||||
data = {}
|
||||
with async_timeout.timeout(20):
|
||||
if self.use_nearest:
|
||||
measurements = self.airly.create_measurements_session_nearest(
|
||||
self.latitude, self.longitude, max_distance_km=5
|
||||
)
|
||||
else:
|
||||
measurements = self.airly.create_measurements_session_point(
|
||||
self.latitude, self.longitude
|
||||
)
|
||||
with async_timeout.timeout(20):
|
||||
try:
|
||||
await measurements.update()
|
||||
except (AirlyError, ClientConnectorError) as error:
|
||||
|
@ -87,13 +87,13 @@ class AirlyAirQuality(CoordinatorEntity, AirQualityEntity):
|
||||
@round_state
|
||||
def particulate_matter_2_5(self):
|
||||
"""Return the particulate matter 2.5 level."""
|
||||
return self.coordinator.data[ATTR_API_PM25]
|
||||
return self.coordinator.data.get(ATTR_API_PM25)
|
||||
|
||||
@property
|
||||
@round_state
|
||||
def particulate_matter_10(self):
|
||||
"""Return the particulate matter 10 level."""
|
||||
return self.coordinator.data[ATTR_API_PM10]
|
||||
return self.coordinator.data.get(ATTR_API_PM10)
|
||||
|
||||
@property
|
||||
def attribution(self):
|
||||
@ -120,12 +120,19 @@ class AirlyAirQuality(CoordinatorEntity, AirQualityEntity):
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
"""Return the state attributes."""
|
||||
return {
|
||||
attrs = {
|
||||
LABEL_AQI_DESCRIPTION: self.coordinator.data[ATTR_API_CAQI_DESCRIPTION],
|
||||
LABEL_ADVICE: self.coordinator.data[ATTR_API_ADVICE],
|
||||
LABEL_AQI_LEVEL: self.coordinator.data[ATTR_API_CAQI_LEVEL],
|
||||
LABEL_PM_2_5_LIMIT: self.coordinator.data[ATTR_API_PM25_LIMIT],
|
||||
LABEL_PM_2_5_PERCENT: round(self.coordinator.data[ATTR_API_PM25_PERCENT]),
|
||||
LABEL_PM_10_LIMIT: self.coordinator.data[ATTR_API_PM10_LIMIT],
|
||||
LABEL_PM_10_PERCENT: round(self.coordinator.data[ATTR_API_PM10_PERCENT]),
|
||||
}
|
||||
if ATTR_API_PM25 in self.coordinator.data:
|
||||
attrs[LABEL_PM_2_5_LIMIT] = self.coordinator.data[ATTR_API_PM25_LIMIT]
|
||||
attrs[LABEL_PM_2_5_PERCENT] = round(
|
||||
self.coordinator.data[ATTR_API_PM25_PERCENT]
|
||||
)
|
||||
if ATTR_API_PM10 in self.coordinator.data:
|
||||
attrs[LABEL_PM_10_LIMIT] = self.coordinator.data[ATTR_API_PM10_LIMIT]
|
||||
attrs[LABEL_PM_10_PERCENT] = round(
|
||||
self.coordinator.data[ATTR_API_PM10_PERCENT]
|
||||
)
|
||||
return attrs
|
||||
|
@ -10,12 +10,17 @@ from homeassistant.const import (
|
||||
CONF_LATITUDE,
|
||||
CONF_LONGITUDE,
|
||||
CONF_NAME,
|
||||
HTTP_NOT_FOUND,
|
||||
HTTP_UNAUTHORIZED,
|
||||
)
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
from .const import DOMAIN, NO_AIRLY_SENSORS # pylint:disable=unused-import
|
||||
from .const import ( # pylint:disable=unused-import
|
||||
CONF_USE_NEAREST,
|
||||
DOMAIN,
|
||||
NO_AIRLY_SENSORS,
|
||||
)
|
||||
|
||||
|
||||
class AirlyFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
@ -27,6 +32,7 @@ class AirlyFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
async def async_step_user(self, user_input=None):
|
||||
"""Handle a flow initialized by the user."""
|
||||
errors = {}
|
||||
use_nearest = False
|
||||
|
||||
websession = async_get_clientsession(self.hass)
|
||||
|
||||
@ -36,23 +42,32 @@ class AirlyFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
)
|
||||
self._abort_if_unique_id_configured()
|
||||
try:
|
||||
location_valid = await test_location(
|
||||
location_point_valid = await test_location(
|
||||
websession,
|
||||
user_input["api_key"],
|
||||
user_input["latitude"],
|
||||
user_input["longitude"],
|
||||
)
|
||||
if not location_point_valid:
|
||||
await test_location(
|
||||
websession,
|
||||
user_input["api_key"],
|
||||
user_input["latitude"],
|
||||
user_input["longitude"],
|
||||
use_nearest=True,
|
||||
)
|
||||
except AirlyError as err:
|
||||
if err.status_code == HTTP_UNAUTHORIZED:
|
||||
errors["base"] = "invalid_api_key"
|
||||
else:
|
||||
if not location_valid:
|
||||
if err.status_code == HTTP_NOT_FOUND:
|
||||
errors["base"] = "wrong_location"
|
||||
|
||||
if not errors:
|
||||
return self.async_create_entry(
|
||||
title=user_input[CONF_NAME], data=user_input
|
||||
)
|
||||
else:
|
||||
if not location_point_valid:
|
||||
use_nearest = True
|
||||
return self.async_create_entry(
|
||||
title=user_input[CONF_NAME],
|
||||
data={**user_input, CONF_USE_NEAREST: use_nearest},
|
||||
)
|
||||
|
||||
return self.async_show_form(
|
||||
step_id="user",
|
||||
@ -74,13 +89,17 @@ class AirlyFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
)
|
||||
|
||||
|
||||
async def test_location(client, api_key, latitude, longitude):
|
||||
async def test_location(client, api_key, latitude, longitude, use_nearest=False):
|
||||
"""Return true if location is valid."""
|
||||
airly = Airly(api_key, client)
|
||||
measurements = airly.create_measurements_session_point(
|
||||
latitude=latitude, longitude=longitude
|
||||
)
|
||||
|
||||
if use_nearest:
|
||||
measurements = airly.create_measurements_session_nearest(
|
||||
latitude=latitude, longitude=longitude, max_distance_km=5
|
||||
)
|
||||
else:
|
||||
measurements = airly.create_measurements_session_point(
|
||||
latitude=latitude, longitude=longitude
|
||||
)
|
||||
with async_timeout.timeout(10):
|
||||
await measurements.update()
|
||||
|
||||
|
@ -13,6 +13,7 @@ ATTR_API_PM25_LIMIT = "PM25_LIMIT"
|
||||
ATTR_API_PM25_PERCENT = "PM25_PERCENT"
|
||||
ATTR_API_PRESSURE = "PRESSURE"
|
||||
ATTR_API_TEMPERATURE = "TEMPERATURE"
|
||||
CONF_USE_NEAREST = "use_nearest"
|
||||
DEFAULT_NAME = "Airly"
|
||||
DOMAIN = "airly"
|
||||
MANUFACTURER = "Airly sp. z o.o."
|
||||
|
@ -67,7 +67,9 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
|
||||
sensors = []
|
||||
for sensor in SENSOR_TYPES:
|
||||
sensors.append(AirlySensor(coordinator, name, sensor))
|
||||
# When we use the nearest method, we are not sure which sensors are available
|
||||
if coordinator.data.get(sensor):
|
||||
sensors.append(AirlySensor(coordinator, name, sensor))
|
||||
|
||||
async_add_entities(sensors, False)
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Die Airly-Integration ist f\u00fcr diese Koordinaten bereits konfiguriert."
|
||||
"already_configured": "Standort ist bereits konfiguriert"
|
||||
},
|
||||
"error": {
|
||||
"invalid_api_key": "Ung\u00fcltiger API-Schl\u00fcssel",
|
||||
"wrong_location": "Keine Airly Luftmessstation an diesem Ort"
|
||||
},
|
||||
"step": {
|
||||
@ -12,7 +13,7 @@
|
||||
"api_key": "API-Schl\u00fcssel",
|
||||
"latitude": "Breitengrad",
|
||||
"longitude": "L\u00e4ngengrad",
|
||||
"name": "Name der Integration"
|
||||
"name": "Name"
|
||||
},
|
||||
"description": "Einrichtung der Airly-Luftqualit\u00e4t Integration. Um einen API-Schl\u00fcssel zu generieren, registriere dich auf https://developer.airly.eu/register",
|
||||
"title": "Airly"
|
||||
@ -21,7 +22,7 @@
|
||||
},
|
||||
"system_health": {
|
||||
"info": {
|
||||
"can_reach_server": "Airly Server erreichen"
|
||||
"can_reach_server": "Airly-Server erreichen"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,4 +1,21 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Konum zaten yap\u0131land\u0131r\u0131lm\u0131\u015f"
|
||||
},
|
||||
"error": {
|
||||
"invalid_api_key": "Ge\u00e7ersiz API anahtar\u0131"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"api_key": "API Anahtar\u0131",
|
||||
"latitude": "Enlem",
|
||||
"longitude": "Boylam"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"system_health": {
|
||||
"info": {
|
||||
"can_reach_server": "Airly sunucusuna eri\u015fin"
|
||||
|
28
homeassistant/components/airly/translations/uk.json
Normal file
28
homeassistant/components/airly/translations/uk.json
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0434\u043b\u044f \u0446\u044c\u043e\u0433\u043e \u043c\u0456\u0441\u0446\u0435\u0437\u043d\u0430\u0445\u043e\u0434\u0436\u0435\u043d\u043d\u044f \u0432\u0436\u0435 \u0432\u0438\u043a\u043e\u043d\u0430\u043d\u0435."
|
||||
},
|
||||
"error": {
|
||||
"invalid_api_key": "\u0425\u0438\u0431\u043d\u0438\u0439 \u043a\u043b\u044e\u0447 API",
|
||||
"wrong_location": "\u0423 \u0446\u0456\u0439 \u043e\u0431\u043b\u0430\u0441\u0442\u0456 \u043d\u0435\u043c\u0430\u0454 \u0432\u0438\u043c\u0456\u0440\u044e\u0432\u0430\u043b\u044c\u043d\u0438\u0445 \u0441\u0442\u0430\u043d\u0446\u0456\u0439 Airly."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"api_key": "\u041a\u043b\u044e\u0447 API",
|
||||
"latitude": "\u0428\u0438\u0440\u043e\u0442\u0430",
|
||||
"longitude": "\u0414\u043e\u0432\u0433\u043e\u0442\u0430",
|
||||
"name": "\u041d\u0430\u0437\u0432\u0430"
|
||||
},
|
||||
"description": "\u0406\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0456\u044f \u0441\u0435\u0440\u0432\u0456\u0441\u0443 \u0437 \u0430\u043d\u0430\u043b\u0456\u0437\u0443 \u044f\u043a\u043e\u0441\u0442\u0456 \u043f\u043e\u0432\u0456\u0442\u0440\u044f Airly. \u0429\u043e\u0431 \u0441\u0442\u0432\u043e\u0440\u0438\u0442\u0438 \u043a\u043b\u044e\u0447 API, \u043f\u0435\u0440\u0435\u0439\u0434\u0456\u0442\u044c \u0437\u0430 \u043f\u043e\u0441\u0438\u043b\u0430\u043d\u043d\u044f\u043c https://developer.airly.eu/register.",
|
||||
"title": "Airly"
|
||||
}
|
||||
}
|
||||
},
|
||||
"system_health": {
|
||||
"info": {
|
||||
"can_reach_server": "\u0414\u043e\u0441\u0442\u0443\u043f \u0434\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 Airly"
|
||||
}
|
||||
}
|
||||
}
|
161
homeassistant/components/airnow/__init__.py
Normal file
161
homeassistant/components/airnow/__init__.py
Normal file
@ -0,0 +1,161 @@
|
||||
"""The AirNow integration."""
|
||||
import asyncio
|
||||
import datetime
|
||||
import logging
|
||||
|
||||
from aiohttp.client_exceptions import ClientConnectorError
|
||||
from pyairnow import WebServiceAPI
|
||||
from pyairnow.conv import aqi_to_concentration
|
||||
from pyairnow.errors import AirNowError
|
||||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, CONF_RADIUS
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.exceptions import ConfigEntryNotReady
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed
|
||||
|
||||
from .const import (
|
||||
ATTR_API_AQI,
|
||||
ATTR_API_AQI_DESCRIPTION,
|
||||
ATTR_API_AQI_LEVEL,
|
||||
ATTR_API_AQI_PARAM,
|
||||
ATTR_API_CAT_DESCRIPTION,
|
||||
ATTR_API_CAT_LEVEL,
|
||||
ATTR_API_CATEGORY,
|
||||
ATTR_API_PM25,
|
||||
ATTR_API_POLLUTANT,
|
||||
ATTR_API_REPORT_DATE,
|
||||
ATTR_API_REPORT_HOUR,
|
||||
ATTR_API_STATE,
|
||||
ATTR_API_STATION,
|
||||
ATTR_API_STATION_LATITUDE,
|
||||
ATTR_API_STATION_LONGITUDE,
|
||||
DOMAIN,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
PLATFORMS = ["sensor"]
|
||||
|
||||
|
||||
async def async_setup(hass: HomeAssistant, config: dict):
|
||||
"""Set up the AirNow component."""
|
||||
return True
|
||||
|
||||
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry):
|
||||
"""Set up AirNow from a config entry."""
|
||||
api_key = entry.data[CONF_API_KEY]
|
||||
latitude = entry.data[CONF_LATITUDE]
|
||||
longitude = entry.data[CONF_LONGITUDE]
|
||||
distance = entry.data[CONF_RADIUS]
|
||||
|
||||
# Reports are published hourly but update twice per hour
|
||||
update_interval = datetime.timedelta(minutes=30)
|
||||
|
||||
# Setup the Coordinator
|
||||
session = async_get_clientsession(hass)
|
||||
coordinator = AirNowDataUpdateCoordinator(
|
||||
hass, session, api_key, latitude, longitude, distance, update_interval
|
||||
)
|
||||
|
||||
# Sync with Coordinator
|
||||
await coordinator.async_refresh()
|
||||
if not coordinator.last_update_success:
|
||||
raise ConfigEntryNotReady
|
||||
|
||||
# Store Entity and Initialize Platforms
|
||||
hass.data.setdefault(DOMAIN, {})
|
||||
hass.data[DOMAIN][entry.entry_id] = coordinator
|
||||
|
||||
for component in PLATFORMS:
|
||||
hass.async_create_task(
|
||||
hass.config_entries.async_forward_entry_setup(entry, component)
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry):
|
||||
"""Unload a config entry."""
|
||||
unload_ok = all(
|
||||
await asyncio.gather(
|
||||
*[
|
||||
hass.config_entries.async_forward_entry_unload(entry, component)
|
||||
for component in PLATFORMS
|
||||
]
|
||||
)
|
||||
)
|
||||
if unload_ok:
|
||||
hass.data[DOMAIN].pop(entry.entry_id)
|
||||
|
||||
return unload_ok
|
||||
|
||||
|
||||
class AirNowDataUpdateCoordinator(DataUpdateCoordinator):
|
||||
"""Define an object to hold Airly data."""
|
||||
|
||||
def __init__(
|
||||
self, hass, session, api_key, latitude, longitude, distance, update_interval
|
||||
):
|
||||
"""Initialize."""
|
||||
self.latitude = latitude
|
||||
self.longitude = longitude
|
||||
self.distance = distance
|
||||
|
||||
self.airnow = WebServiceAPI(api_key, session=session)
|
||||
|
||||
super().__init__(hass, _LOGGER, name=DOMAIN, update_interval=update_interval)
|
||||
|
||||
async def _async_update_data(self):
|
||||
"""Update data via library."""
|
||||
data = {}
|
||||
try:
|
||||
obs = await self.airnow.observations.latLong(
|
||||
self.latitude,
|
||||
self.longitude,
|
||||
distance=self.distance,
|
||||
)
|
||||
|
||||
except (AirNowError, ClientConnectorError) as error:
|
||||
raise UpdateFailed(error) from error
|
||||
|
||||
if not obs:
|
||||
raise UpdateFailed("No data was returned from AirNow")
|
||||
|
||||
max_aqi = 0
|
||||
max_aqi_level = 0
|
||||
max_aqi_desc = ""
|
||||
max_aqi_poll = ""
|
||||
for obv in obs:
|
||||
# Convert AQIs to Concentration
|
||||
pollutant = obv[ATTR_API_AQI_PARAM]
|
||||
concentration = aqi_to_concentration(obv[ATTR_API_AQI], pollutant)
|
||||
data[obv[ATTR_API_AQI_PARAM]] = concentration
|
||||
|
||||
# Overall AQI is the max of all pollutant AQIs
|
||||
if obv[ATTR_API_AQI] > max_aqi:
|
||||
max_aqi = obv[ATTR_API_AQI]
|
||||
max_aqi_level = obv[ATTR_API_CATEGORY][ATTR_API_CAT_LEVEL]
|
||||
max_aqi_desc = obv[ATTR_API_CATEGORY][ATTR_API_CAT_DESCRIPTION]
|
||||
max_aqi_poll = pollutant
|
||||
|
||||
# Copy other data from PM2.5 Value
|
||||
if obv[ATTR_API_AQI_PARAM] == ATTR_API_PM25:
|
||||
# Copy Report Details
|
||||
data[ATTR_API_REPORT_DATE] = obv[ATTR_API_REPORT_DATE]
|
||||
data[ATTR_API_REPORT_HOUR] = obv[ATTR_API_REPORT_HOUR]
|
||||
|
||||
# Copy Station Details
|
||||
data[ATTR_API_STATE] = obv[ATTR_API_STATE]
|
||||
data[ATTR_API_STATION] = obv[ATTR_API_STATION]
|
||||
data[ATTR_API_STATION_LATITUDE] = obv[ATTR_API_STATION_LATITUDE]
|
||||
data[ATTR_API_STATION_LONGITUDE] = obv[ATTR_API_STATION_LONGITUDE]
|
||||
|
||||
# Store Overall AQI
|
||||
data[ATTR_API_AQI] = max_aqi
|
||||
data[ATTR_API_AQI_LEVEL] = max_aqi_level
|
||||
data[ATTR_API_AQI_DESCRIPTION] = max_aqi_desc
|
||||
data[ATTR_API_POLLUTANT] = max_aqi_poll
|
||||
|
||||
return data
|
110
homeassistant/components/airnow/config_flow.py
Normal file
110
homeassistant/components/airnow/config_flow.py
Normal file
@ -0,0 +1,110 @@
|
||||
"""Config flow for AirNow integration."""
|
||||
import logging
|
||||
|
||||
from pyairnow import WebServiceAPI
|
||||
from pyairnow.errors import AirNowError, InvalidKeyError
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant import config_entries, core, exceptions
|
||||
from homeassistant.const import CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, CONF_RADIUS
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
|
||||
from .const import DOMAIN # pylint:disable=unused-import
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def validate_input(hass: core.HomeAssistant, data):
|
||||
"""
|
||||
Validate the user input allows us to connect.
|
||||
|
||||
Data has the keys from DATA_SCHEMA with values provided by the user.
|
||||
"""
|
||||
session = async_get_clientsession(hass)
|
||||
client = WebServiceAPI(data[CONF_API_KEY], session=session)
|
||||
|
||||
lat = data[CONF_LATITUDE]
|
||||
lng = data[CONF_LONGITUDE]
|
||||
distance = data[CONF_RADIUS]
|
||||
|
||||
# Check that the provided latitude/longitude provide a response
|
||||
try:
|
||||
test_data = await client.observations.latLong(lat, lng, distance=distance)
|
||||
|
||||
except InvalidKeyError as exc:
|
||||
raise InvalidAuth from exc
|
||||
except AirNowError as exc:
|
||||
raise CannotConnect from exc
|
||||
|
||||
if not test_data:
|
||||
raise InvalidLocation
|
||||
|
||||
# Validation Succeeded
|
||||
return True
|
||||
|
||||
|
||||
class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
"""Handle a config flow for AirNow."""
|
||||
|
||||
VERSION = 1
|
||||
CONNECTION_CLASS = config_entries.CONN_CLASS_CLOUD_POLL
|
||||
|
||||
async def async_step_user(self, user_input=None):
|
||||
"""Handle the initial step."""
|
||||
errors = {}
|
||||
if user_input is not None:
|
||||
# Set a unique id based on latitude/longitude
|
||||
await self.async_set_unique_id(
|
||||
f"{user_input[CONF_LATITUDE]}-{user_input[CONF_LONGITUDE]}"
|
||||
)
|
||||
self._abort_if_unique_id_configured()
|
||||
|
||||
try:
|
||||
# Validate inputs
|
||||
await validate_input(self.hass, user_input)
|
||||
|
||||
except CannotConnect:
|
||||
errors["base"] = "cannot_connect"
|
||||
except InvalidAuth:
|
||||
errors["base"] = "invalid_auth"
|
||||
except InvalidLocation:
|
||||
errors["base"] = "invalid_location"
|
||||
except Exception: # pylint: disable=broad-except
|
||||
_LOGGER.exception("Unexpected exception")
|
||||
errors["base"] = "unknown"
|
||||
else:
|
||||
# Create Entry
|
||||
return self.async_create_entry(
|
||||
title=f"AirNow Sensor at {user_input[CONF_LATITUDE]}, {user_input[CONF_LONGITUDE]}",
|
||||
data=user_input,
|
||||
)
|
||||
|
||||
return self.async_show_form(
|
||||
step_id="user",
|
||||
data_schema=vol.Schema(
|
||||
{
|
||||
vol.Required(CONF_API_KEY): str,
|
||||
vol.Optional(
|
||||
CONF_LATITUDE, default=self.hass.config.latitude
|
||||
): cv.latitude,
|
||||
vol.Optional(
|
||||
CONF_LONGITUDE, default=self.hass.config.longitude
|
||||
): cv.longitude,
|
||||
vol.Optional(CONF_RADIUS, default=150): int,
|
||||
}
|
||||
),
|
||||
errors=errors,
|
||||
)
|
||||
|
||||
|
||||
class CannotConnect(exceptions.HomeAssistantError):
|
||||
"""Error to indicate we cannot connect."""
|
||||
|
||||
|
||||
class InvalidAuth(exceptions.HomeAssistantError):
|
||||
"""Error to indicate there is invalid auth."""
|
||||
|
||||
|
||||
class InvalidLocation(exceptions.HomeAssistantError):
|
||||
"""Error to indicate the location is invalid."""
|
21
homeassistant/components/airnow/const.py
Normal file
21
homeassistant/components/airnow/const.py
Normal file
@ -0,0 +1,21 @@
|
||||
"""Constants for the AirNow integration."""
|
||||
ATTR_API_AQI = "AQI"
|
||||
ATTR_API_AQI_LEVEL = "Category.Number"
|
||||
ATTR_API_AQI_DESCRIPTION = "Category.Name"
|
||||
ATTR_API_AQI_PARAM = "ParameterName"
|
||||
ATTR_API_CATEGORY = "Category"
|
||||
ATTR_API_CAT_LEVEL = "Number"
|
||||
ATTR_API_CAT_DESCRIPTION = "Name"
|
||||
ATTR_API_O3 = "O3"
|
||||
ATTR_API_PM25 = "PM2.5"
|
||||
ATTR_API_POLLUTANT = "Pollutant"
|
||||
ATTR_API_REPORT_DATE = "HourObserved"
|
||||
ATTR_API_REPORT_HOUR = "DateObserved"
|
||||
ATTR_API_STATE = "StateCode"
|
||||
ATTR_API_STATION = "ReportingArea"
|
||||
ATTR_API_STATION_LATITUDE = "Latitude"
|
||||
ATTR_API_STATION_LONGITUDE = "Longitude"
|
||||
DEFAULT_NAME = "AirNow"
|
||||
DOMAIN = "airnow"
|
||||
SENSOR_AQI_ATTR_DESCR = "description"
|
||||
SENSOR_AQI_ATTR_LEVEL = "level"
|
12
homeassistant/components/airnow/manifest.json
Normal file
12
homeassistant/components/airnow/manifest.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"domain": "airnow",
|
||||
"name": "AirNow",
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/airnow",
|
||||
"requirements": [
|
||||
"pyairnow==1.1.0"
|
||||
],
|
||||
"codeowners": [
|
||||
"@asymworks"
|
||||
]
|
||||
}
|
118
homeassistant/components/airnow/sensor.py
Normal file
118
homeassistant/components/airnow/sensor.py
Normal file
@ -0,0 +1,118 @@
|
||||
"""Support for the AirNow sensor service."""
|
||||
from homeassistant.const import (
|
||||
ATTR_ATTRIBUTION,
|
||||
ATTR_DEVICE_CLASS,
|
||||
CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
CONCENTRATION_PARTS_PER_MILLION,
|
||||
)
|
||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||
|
||||
from .const import (
|
||||
ATTR_API_AQI,
|
||||
ATTR_API_AQI_DESCRIPTION,
|
||||
ATTR_API_AQI_LEVEL,
|
||||
ATTR_API_O3,
|
||||
ATTR_API_PM25,
|
||||
DOMAIN,
|
||||
SENSOR_AQI_ATTR_DESCR,
|
||||
SENSOR_AQI_ATTR_LEVEL,
|
||||
)
|
||||
|
||||
ATTRIBUTION = "Data provided by AirNow"
|
||||
|
||||
ATTR_ICON = "icon"
|
||||
ATTR_LABEL = "label"
|
||||
ATTR_UNIT = "unit"
|
||||
|
||||
PARALLEL_UPDATES = 1
|
||||
|
||||
SENSOR_TYPES = {
|
||||
ATTR_API_AQI: {
|
||||
ATTR_DEVICE_CLASS: None,
|
||||
ATTR_ICON: "mdi:blur",
|
||||
ATTR_LABEL: ATTR_API_AQI,
|
||||
ATTR_UNIT: "aqi",
|
||||
},
|
||||
ATTR_API_PM25: {
|
||||
ATTR_DEVICE_CLASS: None,
|
||||
ATTR_ICON: "mdi:blur",
|
||||
ATTR_LABEL: ATTR_API_PM25,
|
||||
ATTR_UNIT: CONCENTRATION_MICROGRAMS_PER_CUBIC_METER,
|
||||
},
|
||||
ATTR_API_O3: {
|
||||
ATTR_DEVICE_CLASS: None,
|
||||
ATTR_ICON: "mdi:blur",
|
||||
ATTR_LABEL: ATTR_API_O3,
|
||||
ATTR_UNIT: CONCENTRATION_PARTS_PER_MILLION,
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up AirNow sensor entities based on a config entry."""
|
||||
coordinator = hass.data[DOMAIN][config_entry.entry_id]
|
||||
|
||||
sensors = []
|
||||
for sensor in SENSOR_TYPES:
|
||||
sensors.append(AirNowSensor(coordinator, sensor))
|
||||
|
||||
async_add_entities(sensors, False)
|
||||
|
||||
|
||||
class AirNowSensor(CoordinatorEntity):
|
||||
"""Define an AirNow sensor."""
|
||||
|
||||
def __init__(self, coordinator, kind):
|
||||
"""Initialize."""
|
||||
super().__init__(coordinator)
|
||||
self.kind = kind
|
||||
self._device_class = None
|
||||
self._state = None
|
||||
self._icon = None
|
||||
self._unit_of_measurement = None
|
||||
self._attrs = {ATTR_ATTRIBUTION: ATTRIBUTION}
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name."""
|
||||
return f"AirNow {SENSOR_TYPES[self.kind][ATTR_LABEL]}"
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Return the state."""
|
||||
self._state = self.coordinator.data[self.kind]
|
||||
return self._state
|
||||
|
||||
@property
|
||||
def device_state_attributes(self):
|
||||
"""Return the state attributes."""
|
||||
if self.kind == ATTR_API_AQI:
|
||||
self._attrs[SENSOR_AQI_ATTR_DESCR] = self.coordinator.data[
|
||||
ATTR_API_AQI_DESCRIPTION
|
||||
]
|
||||
self._attrs[SENSOR_AQI_ATTR_LEVEL] = self.coordinator.data[
|
||||
ATTR_API_AQI_LEVEL
|
||||
]
|
||||
|
||||
return self._attrs
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Return the icon."""
|
||||
self._icon = SENSOR_TYPES[self.kind][ATTR_ICON]
|
||||
return self._icon
|
||||
|
||||
@property
|
||||
def device_class(self):
|
||||
"""Return the device_class."""
|
||||
return SENSOR_TYPES[self.kind][ATTR_DEVICE_CLASS]
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
"""Return a unique_id for this entity."""
|
||||
return f"{self.coordinator.latitude}-{self.coordinator.longitude}-{self.kind.lower()}"
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
"""Return the unit the value is expressed in."""
|
||||
return SENSOR_TYPES[self.kind][ATTR_UNIT]
|
26
homeassistant/components/airnow/strings.json
Normal file
26
homeassistant/components/airnow/strings.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"title": "AirNow",
|
||||
"config": {
|
||||
"step": {
|
||||
"user": {
|
||||
"title": "AirNow",
|
||||
"description": "Set up AirNow air quality integration. To generate API key go to https://docs.airnowapi.org/account/request/",
|
||||
"data": {
|
||||
"api_key": "[%key:common::config_flow::data::api_key%]",
|
||||
"latitude": "[%key:common::config_flow::data::latitude%]",
|
||||
"longitude": "[%key:common::config_flow::data::longitude%]",
|
||||
"radius": "Station Radius (miles; optional)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
|
||||
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
|
||||
"invalid_location": "No results found for that location",
|
||||
"unknown": "[%key:common::config_flow::error::unknown%]"
|
||||
},
|
||||
"abort": {
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
|
||||
}
|
||||
}
|
||||
}
|
26
homeassistant/components/airnow/translations/ca.json
Normal file
26
homeassistant/components/airnow/translations/ca.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "El dispositiu ja est\u00e0 configurat"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Ha fallat la connexi\u00f3",
|
||||
"invalid_auth": "Autenticaci\u00f3 inv\u00e0lida",
|
||||
"invalid_location": "No s'ha trobat cap resultat per a aquesta ubicaci\u00f3",
|
||||
"unknown": "Error inesperat"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"api_key": "Clau API",
|
||||
"latitude": "Latitud",
|
||||
"longitude": "Longitud",
|
||||
"radius": "Radi de l'estaci\u00f3 (milles; opcional)"
|
||||
},
|
||||
"description": "Configura la integraci\u00f3 de qualitat d'aire AirNow. Per generar la clau API, v\u00e9s a https://docs.airnowapi.org/account/request/",
|
||||
"title": "AirNow"
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "AirNow"
|
||||
}
|
23
homeassistant/components/airnow/translations/cs.json
Normal file
23
homeassistant/components/airnow/translations/cs.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Za\u0159\u00edzen\u00ed je ji\u017e nastaveno"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Nepoda\u0159ilo se p\u0159ipojit",
|
||||
"invalid_auth": "Neplatn\u00e9 ov\u011b\u0159en\u00ed",
|
||||
"unknown": "Neo\u010dek\u00e1van\u00e1 chyba"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"api_key": "Kl\u00ed\u010d API",
|
||||
"latitude": "Zem\u011bpisn\u00e1 \u0161\u00ed\u0159ka",
|
||||
"longitude": "Zem\u011bpisn\u00e1 d\u00e9lka"
|
||||
},
|
||||
"title": "AirNow"
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "AirNow"
|
||||
}
|
24
homeassistant/components/airnow/translations/de.json
Normal file
24
homeassistant/components/airnow/translations/de.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Ger\u00e4t ist bereits konfiguriert"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Verbindung fehlgeschlagen",
|
||||
"invalid_auth": "Ung\u00fcltige Authentifizierung",
|
||||
"invalid_location": "F\u00fcr diesen Standort wurden keine Ergebnisse gefunden",
|
||||
"unknown": "Unerwarteter Fehler"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"api_key": "API-Schl\u00fcssel",
|
||||
"latitude": "Breitengrad",
|
||||
"longitude": "L\u00e4ngengrad"
|
||||
},
|
||||
"title": "AirNow"
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "AirNow"
|
||||
}
|
26
homeassistant/components/airnow/translations/en.json
Normal file
26
homeassistant/components/airnow/translations/en.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Device is already configured"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Failed to connect",
|
||||
"invalid_auth": "Invalid authentication",
|
||||
"invalid_location": "No results found for that location",
|
||||
"unknown": "Unexpected error"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"api_key": "API Key",
|
||||
"latitude": "Latitude",
|
||||
"longitude": "Longitude",
|
||||
"radius": "Station Radius (miles; optional)"
|
||||
},
|
||||
"description": "Set up AirNow air quality integration. To generate API key go to https://docs.airnowapi.org/account/request/",
|
||||
"title": "AirNow"
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "AirNow"
|
||||
}
|
26
homeassistant/components/airnow/translations/es.json
Normal file
26
homeassistant/components/airnow/translations/es.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "El dispositivo ya est\u00e1 configurado"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "No se pudo conectar",
|
||||
"invalid_auth": "Autenticaci\u00f3n no v\u00e1lida",
|
||||
"invalid_location": "No se han encontrado resultados para esa ubicaci\u00f3n",
|
||||
"unknown": "Error inesperado"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"api_key": "Clave API",
|
||||
"latitude": "Latitud",
|
||||
"longitude": "Longitud",
|
||||
"radius": "Radio de la estaci\u00f3n (millas; opcional)"
|
||||
},
|
||||
"description": "Configurar la integraci\u00f3n de calidad del aire de AirNow. Para generar una clave API, ve a https://docs.airnowapi.org/account/request/",
|
||||
"title": "AirNow"
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "AirNow"
|
||||
}
|
26
homeassistant/components/airnow/translations/et.json
Normal file
26
homeassistant/components/airnow/translations/et.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Seade on juba h\u00e4\u00e4lestatud"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "\u00dchendamine nurjus",
|
||||
"invalid_auth": "Vigane autentimine",
|
||||
"invalid_location": "Selle asukoha jaoks ei leitud andmeid",
|
||||
"unknown": "Ootamatu t\u00f5rge"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"api_key": "API v\u00f5ti",
|
||||
"latitude": "Laiuskraad",
|
||||
"longitude": "Pikkuskraad",
|
||||
"radius": "Jaama raadius (miilid; valikuline)"
|
||||
},
|
||||
"description": "Seadista AirNow \u00f5hukvaliteedi sidumine. API-v\u00f5tme loomiseks mine aadressile https://docs.airnowapi.org/account/request/",
|
||||
"title": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": ""
|
||||
}
|
26
homeassistant/components/airnow/translations/fr.json
Normal file
26
homeassistant/components/airnow/translations/fr.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "L'appareil est d\u00e9j\u00e0 configur\u00e9"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "\u00c9chec \u00e0 la connexion",
|
||||
"invalid_auth": "Authentification invalide",
|
||||
"invalid_location": "Aucun r\u00e9sultat trouv\u00e9 pour cet emplacement",
|
||||
"unknown": "Erreur inattendue"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"api_key": "Cl\u00e9 API",
|
||||
"latitude": "Latitude",
|
||||
"longitude": "Longitude",
|
||||
"radius": "Rayon d'action de la station (en miles, facultatif)"
|
||||
},
|
||||
"description": "Configurez l'int\u00e9gration de la qualit\u00e9 de l'air AirNow. Pour g\u00e9n\u00e9rer la cl\u00e9 API, acc\u00e9dez \u00e0 https://docs.airnowapi.org/account/request/",
|
||||
"title": "AirNow"
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "AirNow"
|
||||
}
|
26
homeassistant/components/airnow/translations/it.json
Normal file
26
homeassistant/components/airnow/translations/it.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Il dispositivo \u00e8 gi\u00e0 configurato"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Impossibile connettersi",
|
||||
"invalid_auth": "Autenticazione non valida",
|
||||
"invalid_location": "Nessun risultato trovato per quella localit\u00e0",
|
||||
"unknown": "Errore imprevisto"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"api_key": "Chiave API",
|
||||
"latitude": "Latitudine",
|
||||
"longitude": "Logitudine",
|
||||
"radius": "Raggio stazione (miglia; opzionale)"
|
||||
},
|
||||
"description": "Configura l'integrazione per la qualit\u00e0 dell'aria AirNow. Per generare la chiave API, vai su https://docs.airnowapi.org/account/request/",
|
||||
"title": "AirNow"
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "AirNow"
|
||||
}
|
24
homeassistant/components/airnow/translations/lb.json
Normal file
24
homeassistant/components/airnow/translations/lb.json
Normal file
@ -0,0 +1,24 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Apparat ass scho konfigur\u00e9iert"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Feeler beim verbannen",
|
||||
"invalid_auth": "Ong\u00eblteg Authentifikatioun",
|
||||
"invalid_location": "Keng Resultater fonnt fir d\u00ebse Standuert",
|
||||
"unknown": "Onerwaarte Feeler"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"api_key": "API Schl\u00ebssel",
|
||||
"latitude": "L\u00e4ngegrad",
|
||||
"longitude": "Breedegrag"
|
||||
},
|
||||
"title": "AirNow"
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "AirNow"
|
||||
}
|
26
homeassistant/components/airnow/translations/no.json
Normal file
26
homeassistant/components/airnow/translations/no.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Enheten er allerede konfigurert"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Tilkobling mislyktes",
|
||||
"invalid_auth": "Ugyldig godkjenning",
|
||||
"invalid_location": "Ingen resultater funnet for den plasseringen",
|
||||
"unknown": "Uventet feil"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"api_key": "API-n\u00f8kkel",
|
||||
"latitude": "Breddegrad",
|
||||
"longitude": "Lengdegrad",
|
||||
"radius": "Stasjonsradius (miles; valgfritt)"
|
||||
},
|
||||
"description": "Konfigurer integrering av luftkvalitet i AirNow. For \u00e5 generere en API-n\u00f8kkel, g\u00e5r du til https://docs.airnowapi.org/account/request/",
|
||||
"title": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": ""
|
||||
}
|
26
homeassistant/components/airnow/translations/pl.json
Normal file
26
homeassistant/components/airnow/translations/pl.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Urz\u0105dzenie jest ju\u017c skonfigurowane"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Nie mo\u017cna nawi\u0105za\u0107 po\u0142\u0105czenia",
|
||||
"invalid_auth": "Niepoprawne uwierzytelnienie",
|
||||
"invalid_location": "Brak wynik\u00f3w dla tej lokalizacji",
|
||||
"unknown": "Nieoczekiwany b\u0142\u0105d"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"api_key": "Klucz API",
|
||||
"latitude": "Szeroko\u015b\u0107 geograficzna",
|
||||
"longitude": "D\u0142ugo\u015b\u0107 geograficzna",
|
||||
"radius": "Promie\u0144 od stacji (w milach; opcjonalnie)"
|
||||
},
|
||||
"description": "Konfiguracja integracji jako\u015bci powietrza AirNow. Aby wygenerowa\u0107 klucz API, przejd\u017a do https://docs.airnowapi.org/account/request/",
|
||||
"title": "AirNow"
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "AirNow"
|
||||
}
|
23
homeassistant/components/airnow/translations/pt.json
Normal file
23
homeassistant/components/airnow/translations/pt.json
Normal file
@ -0,0 +1,23 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "O dispositivo j\u00e1 est\u00e1 configurado"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Falha na liga\u00e7\u00e3o",
|
||||
"invalid_auth": "Autentica\u00e7\u00e3o inv\u00e1lida",
|
||||
"unknown": "Erro inesperado"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"api_key": "API Key",
|
||||
"latitude": "Latitude",
|
||||
"longitude": "Longitude"
|
||||
},
|
||||
"title": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": ""
|
||||
}
|
26
homeassistant/components/airnow/translations/ru.json
Normal file
26
homeassistant/components/airnow/translations/ru.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "\u042d\u0442\u043e \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e \u0443\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u0432 Home Assistant."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f.",
|
||||
"invalid_auth": "\u041d\u0435\u0432\u0435\u0440\u043d\u0430\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f.",
|
||||
"invalid_location": "\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u0435\u0441\u0442\u043e\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043e.",
|
||||
"unknown": "\u041d\u0435\u043f\u0440\u0435\u0434\u0432\u0438\u0434\u0435\u043d\u043d\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"api_key": "\u041a\u043b\u044e\u0447 API",
|
||||
"latitude": "\u0428\u0438\u0440\u043e\u0442\u0430",
|
||||
"longitude": "\u0414\u043e\u043b\u0433\u043e\u0442\u0430",
|
||||
"radius": "\u0420\u0430\u0434\u0438\u0443\u0441 \u0441\u0442\u0430\u043d\u0446\u0438\u0438 (\u0432 \u043c\u0438\u043b\u044f\u0445; \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e)"
|
||||
},
|
||||
"description": "\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u043f\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0443 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0430 \u0432\u043e\u0437\u0434\u0443\u0445\u0430 AirNow. \u0427\u0442\u043e\u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043b\u044e\u0447 API, \u043f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 https://docs.airnowapi.org/account/request/.",
|
||||
"title": "AirNow"
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "AirNow"
|
||||
}
|
25
homeassistant/components/airnow/translations/tr.json
Normal file
25
homeassistant/components/airnow/translations/tr.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"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_location": "Bu konum i\u00e7in hi\u00e7bir sonu\u00e7 bulunamad\u0131",
|
||||
"unknown": "Beklenmeyen hata"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"api_key": "API Anahtar\u0131",
|
||||
"latitude": "Enlem",
|
||||
"longitude": "Boylam",
|
||||
"radius": "\u0130stasyon Yar\u0131\u00e7ap\u0131 (mil; iste\u011fe ba\u011fl\u0131)"
|
||||
},
|
||||
"title": "AirNow"
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "AirNow"
|
||||
}
|
26
homeassistant/components/airnow/translations/uk.json
Normal file
26
homeassistant/components/airnow/translations/uk.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "\u0426\u0435\u0439 \u043f\u0440\u0438\u0441\u0442\u0440\u0456\u0439 \u0432\u0436\u0435 \u0434\u043e\u0434\u0430\u043d\u043e \u0432 Home Assistant."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "\u041d\u0435 \u0432\u0434\u0430\u043b\u043e\u0441\u044f \u043f\u0456\u0434'\u0454\u0434\u043d\u0430\u0442\u0438\u0441\u044f",
|
||||
"invalid_auth": "\u041d\u0435\u0432\u0456\u0440\u043d\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0456\u043a\u0430\u0446\u0456\u044f.",
|
||||
"invalid_location": "\u041d\u0435 \u0437\u043d\u0430\u0439\u0434\u0435\u043d\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0456\u0432 \u0434\u043b\u044f \u0446\u044c\u043e\u0433\u043e \u043c\u0456\u0441\u0446\u0435\u0437\u043d\u0430\u0445\u043e\u0434\u0436\u0435\u043d\u043d\u044f",
|
||||
"unknown": "\u041d\u0435\u043e\u0447\u0456\u043a\u0443\u0432\u0430\u043d\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"api_key": "\u041a\u043b\u044e\u0447 API",
|
||||
"latitude": "\u0428\u0438\u0440\u043e\u0442\u0430",
|
||||
"longitude": "\u0414\u043e\u0432\u0433\u043e\u0442\u0430",
|
||||
"radius": "\u0420\u0430\u0434\u0456\u0443\u0441 \u0441\u0442\u0430\u043d\u0446\u0456\u0457 (\u043c\u0438\u043b\u0456; \u043d\u0435\u043e\u0431\u043e\u0432\u2019\u044f\u0437\u043a\u043e\u0432\u043e)"
|
||||
},
|
||||
"description": "\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0439\u0442\u0435 \u0456\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0456\u044e \u044f\u043a\u043e\u0441\u0442\u0456 \u043f\u043e\u0432\u0456\u0442\u0440\u044f AirNow. \u0429\u043e\u0431 \u0437\u0433\u0435\u043d\u0435\u0440\u0443\u0432\u0430\u0442\u0438 \u043a\u043b\u044e\u0447 API, \u043f\u0435\u0440\u0435\u0439\u0434\u0456\u0442\u044c \u043d\u0430 \u0441\u0442\u043e\u0440\u0456\u043d\u043a\u0443 https://docs.airnowapi.org/account/request/",
|
||||
"title": "AirNow"
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "AirNow"
|
||||
}
|
26
homeassistant/components/airnow/translations/zh-Hant.json
Normal file
26
homeassistant/components/airnow/translations/zh-Hant.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "\u88dd\u7f6e\u7d93\u8a2d\u5b9a\u5b8c\u6210"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "\u9023\u7dda\u5931\u6557",
|
||||
"invalid_auth": "\u9a57\u8b49\u78bc\u7121\u6548",
|
||||
"invalid_location": "\u627e\u4e0d\u5230\u8a72\u4f4d\u7f6e\u7684\u7d50\u679c",
|
||||
"unknown": "\u672a\u9810\u671f\u932f\u8aa4"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"api_key": "API \u5bc6\u9470",
|
||||
"latitude": "\u7def\u5ea6",
|
||||
"longitude": "\u7d93\u5ea6",
|
||||
"radius": "\u89c0\u6e2c\u7ad9\u534a\u5f91\uff08\u82f1\u91cc\uff1b\u9078\u9805\uff09"
|
||||
},
|
||||
"description": "\u6b32\u8a2d\u5b9a AirNow \u7a7a\u6c23\u54c1\u8cea\u6574\u5408\u3002\u8acb\u81f3 https://docs.airnowapi.org/account/request/ \u7522\u751f API \u5bc6\u9470",
|
||||
"title": "AirNow"
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "AirNow"
|
||||
}
|
@ -58,25 +58,6 @@ NODE_PRO_SENSORS = [
|
||||
(SENSOR_KIND_TEMPERATURE, "Temperature", DEVICE_CLASS_TEMPERATURE, TEMP_CELSIUS),
|
||||
]
|
||||
|
||||
POLLUTANT_LEVEL_MAPPING = [
|
||||
{"label": "Good", "icon": "mdi:emoticon-excited", "minimum": 0, "maximum": 50},
|
||||
{"label": "Moderate", "icon": "mdi:emoticon-happy", "minimum": 51, "maximum": 100},
|
||||
{
|
||||
"label": "Unhealthy for sensitive groups",
|
||||
"icon": "mdi:emoticon-neutral",
|
||||
"minimum": 101,
|
||||
"maximum": 150,
|
||||
},
|
||||
{"label": "Unhealthy", "icon": "mdi:emoticon-sad", "minimum": 151, "maximum": 200},
|
||||
{
|
||||
"label": "Very Unhealthy",
|
||||
"icon": "mdi:emoticon-dead",
|
||||
"minimum": 201,
|
||||
"maximum": 300,
|
||||
},
|
||||
{"label": "Hazardous", "icon": "mdi:biohazard", "minimum": 301, "maximum": 10000},
|
||||
]
|
||||
|
||||
POLLUTANT_MAPPING = {
|
||||
"co": {"label": "Carbon Monoxide", "unit": CONCENTRATION_PARTS_PER_MILLION},
|
||||
"n2": {"label": "Nitrogen Dioxide", "unit": CONCENTRATION_PARTS_PER_BILLION},
|
||||
@ -87,6 +68,22 @@ POLLUTANT_MAPPING = {
|
||||
}
|
||||
|
||||
|
||||
@callback
|
||||
def async_get_pollutant_level_info(value):
|
||||
"""Return a verbal pollutant level (and associated icon) for a numeric value."""
|
||||
if 0 <= value <= 50:
|
||||
return ("Good", "mdi:emoticon-excited")
|
||||
if 51 <= value <= 100:
|
||||
return ("Moderate", "mdi:emoticon-happy")
|
||||
if 101 <= value <= 150:
|
||||
return ("Unhealthy for sensitive groups", "mdi:emoticon-neutral")
|
||||
if 151 <= value <= 200:
|
||||
return ("Unhealthy", "mdi:emoticon-sad")
|
||||
if 201 <= value <= 300:
|
||||
return ("Very Unhealthy", "mdi:emoticon-dead")
|
||||
return ("Hazardous", "mdi:biohazard")
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up AirVisual sensors based on a config entry."""
|
||||
coordinator = hass.data[DOMAIN][DATA_COORDINATOR][config_entry.entry_id]
|
||||
@ -171,13 +168,7 @@ class AirVisualGeographySensor(AirVisualEntity):
|
||||
|
||||
if self._kind == SENSOR_KIND_LEVEL:
|
||||
aqi = data[f"aqi{self._locale}"]
|
||||
[level] = [
|
||||
i
|
||||
for i in POLLUTANT_LEVEL_MAPPING
|
||||
if i["minimum"] <= aqi <= i["maximum"]
|
||||
]
|
||||
self._state = level["label"]
|
||||
self._icon = level["icon"]
|
||||
self._state, self._icon = async_get_pollutant_level_info(aqi)
|
||||
elif self._kind == SENSOR_KIND_AQI:
|
||||
self._state = data[f"aqi{self._locale}"]
|
||||
elif self._kind == SENSOR_KIND_POLLUTANT:
|
||||
|
11
homeassistant/components/airvisual/translations/ar.json
Normal file
11
homeassistant/components/airvisual/translations/ar.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"config": {
|
||||
"step": {
|
||||
"geography_by_name": {
|
||||
"data": {
|
||||
"country": "\u0627\u0644\u062f\u0648\u0644\u0629"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -7,7 +7,8 @@
|
||||
"error": {
|
||||
"cannot_connect": "Ha fallat la connexi\u00f3",
|
||||
"general_error": "Error inesperat",
|
||||
"invalid_api_key": "Clau API inv\u00e0lida"
|
||||
"invalid_api_key": "Clau API inv\u00e0lida",
|
||||
"location_not_found": "No s'ha trobat la ubicaci\u00f3"
|
||||
},
|
||||
"step": {
|
||||
"geography": {
|
||||
@ -17,7 +18,26 @@
|
||||
"longitude": "Longitud"
|
||||
},
|
||||
"description": "Utilitza l'API d'AirVisual per monitoritzar una ubicaci\u00f3 geogr\u00e0fica.",
|
||||
"title": "Configuraci\u00f3 localitzaci\u00f3 geogr\u00e0fica"
|
||||
"title": "Configura una ubicaci\u00f3 geogr\u00e0fica"
|
||||
},
|
||||
"geography_by_coords": {
|
||||
"data": {
|
||||
"api_key": "Clau API",
|
||||
"latitude": "Latitud",
|
||||
"longitude": "Longitud"
|
||||
},
|
||||
"description": "Utilitza l'API d'AirVisual per monitoritzar una latitud/longitud.",
|
||||
"title": "Configura una ubicaci\u00f3 geogr\u00e0fica"
|
||||
},
|
||||
"geography_by_name": {
|
||||
"data": {
|
||||
"api_key": "Clau API",
|
||||
"city": "Ciutat",
|
||||
"country": "Pa\u00eds",
|
||||
"state": "Estat"
|
||||
},
|
||||
"description": "Utilitza l'API d'AirVisual per monitoritzar un/a ciutat/estat/pa\u00eds",
|
||||
"title": "Configura una ubicaci\u00f3 geogr\u00e0fica"
|
||||
},
|
||||
"node_pro": {
|
||||
"data": {
|
||||
|
@ -1,12 +1,13 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Diese Koordinaten oder Node/Pro ID sind bereits registriert."
|
||||
"already_configured": "Diese Koordinaten oder Node/Pro ID sind bereits registriert.",
|
||||
"reauth_successful": "Die erneute Authentifizierung war erfolgreich"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Verbindungsfehler",
|
||||
"general_error": "Es gab einen unbekannten Fehler.",
|
||||
"invalid_api_key": "Ung\u00fcltiger API-Schl\u00fcssel bereitgestellt."
|
||||
"cannot_connect": "Verbindung fehlgeschlagen",
|
||||
"general_error": "Unerwarteter Fehler",
|
||||
"invalid_api_key": "Ung\u00fcltiger API-Schl\u00fcssel"
|
||||
},
|
||||
"step": {
|
||||
"geography": {
|
||||
@ -19,7 +20,7 @@
|
||||
},
|
||||
"node_pro": {
|
||||
"data": {
|
||||
"ip_address": "IP-Adresse/Hostname des Ger\u00e4ts",
|
||||
"ip_address": "Host",
|
||||
"password": "Passwort"
|
||||
},
|
||||
"description": "\u00dcberwachen Sie eine pers\u00f6nliche AirVisual-Einheit. Das Passwort kann von der Benutzeroberfl\u00e4che des Ger\u00e4ts abgerufen werden.",
|
||||
|
@ -19,6 +19,15 @@
|
||||
"description": "Use the AirVisual cloud API to monitor a geographical location.",
|
||||
"title": "Configure a Geography"
|
||||
},
|
||||
"geography_by_coords": {
|
||||
"data": {
|
||||
"api_key": "API Key",
|
||||
"latitude": "Latitude",
|
||||
"longitude": "Longitude"
|
||||
},
|
||||
"description": "Use the AirVisual cloud API to monitor a geographical location.",
|
||||
"title": "Configure a Geography"
|
||||
},
|
||||
"node_pro": {
|
||||
"data": {
|
||||
"ip_address": "Host",
|
||||
@ -54,4 +63,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,8 @@
|
||||
"error": {
|
||||
"cannot_connect": "\u00dchendamine nurjus",
|
||||
"general_error": "Tundmatu viga",
|
||||
"invalid_api_key": "Vale API v\u00f5ti"
|
||||
"invalid_api_key": "Vale API v\u00f5ti",
|
||||
"location_not_found": "Asukohta ei leitud"
|
||||
},
|
||||
"step": {
|
||||
"geography": {
|
||||
@ -19,6 +20,25 @@
|
||||
"description": "Kasutage AirVisual pilve API-t geograafilise asukoha j\u00e4lgimiseks.",
|
||||
"title": "Seadista Geography"
|
||||
},
|
||||
"geography_by_coords": {
|
||||
"data": {
|
||||
"api_key": "API v\u00f5ti",
|
||||
"latitude": "Laiuskraad",
|
||||
"longitude": "Pikkuskraad"
|
||||
},
|
||||
"description": "Kasuta AirVisual pilve API-t pikkus/laiuskraadi j\u00e4lgimiseks.",
|
||||
"title": "Seadista Geography sidumine"
|
||||
},
|
||||
"geography_by_name": {
|
||||
"data": {
|
||||
"api_key": "API v\u00f5ti",
|
||||
"city": "Linn",
|
||||
"country": "Riik",
|
||||
"state": "olek"
|
||||
},
|
||||
"description": "Kasuta AirVisual pilve API-t linna/osariigi/riigi j\u00e4lgimiseks.",
|
||||
"title": "Seadista Geography sidumine"
|
||||
},
|
||||
"node_pro": {
|
||||
"data": {
|
||||
"ip_address": "\u00dcksuse IP-aadress / hostinimi",
|
||||
|
@ -6,8 +6,8 @@
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "\u00c9chec de connexion",
|
||||
"general_error": "Une erreur inconnue est survenue.",
|
||||
"invalid_api_key": "La cl\u00e9 API fournie n'est pas valide."
|
||||
"general_error": "Erreur inattendue",
|
||||
"invalid_api_key": "Cl\u00e9 API invalide"
|
||||
},
|
||||
"step": {
|
||||
"geography": {
|
||||
@ -21,11 +21,11 @@
|
||||
},
|
||||
"node_pro": {
|
||||
"data": {
|
||||
"ip_address": "Adresse IP / nom d'h\u00f4te de l'unit\u00e9",
|
||||
"ip_address": "H\u00f4te",
|
||||
"password": "Mot de passe"
|
||||
},
|
||||
"description": "Surveillez une unit\u00e9 AirVisual personnelle. Le mot de passe peut \u00eatre r\u00e9cup\u00e9r\u00e9 dans l'interface utilisateur de l'unit\u00e9.",
|
||||
"title": "Configurer un AirVisual Node/Pro"
|
||||
"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": {
|
||||
|
@ -7,7 +7,8 @@
|
||||
"error": {
|
||||
"cannot_connect": "Tilkobling mislyktes",
|
||||
"general_error": "Uventet feil",
|
||||
"invalid_api_key": "Ugyldig API-n\u00f8kkel"
|
||||
"invalid_api_key": "Ugyldig API-n\u00f8kkel",
|
||||
"location_not_found": "Stedet ble ikke funnet"
|
||||
},
|
||||
"step": {
|
||||
"geography": {
|
||||
@ -19,6 +20,25 @@
|
||||
"description": "Bruk AirVisual cloud API til \u00e5 overv\u00e5ke en geografisk plassering.",
|
||||
"title": "Konfigurer en Geography"
|
||||
},
|
||||
"geography_by_coords": {
|
||||
"data": {
|
||||
"api_key": "API-n\u00f8kkel",
|
||||
"latitude": "Breddegrad",
|
||||
"longitude": "Lengdegrad"
|
||||
},
|
||||
"description": "Bruk AirVisual cloud API til \u00e5 overv\u00e5ke en breddegrad/lengdegrad.",
|
||||
"title": "Konfigurer en Geography"
|
||||
},
|
||||
"geography_by_name": {
|
||||
"data": {
|
||||
"api_key": "API-n\u00f8kkel",
|
||||
"city": "By",
|
||||
"country": "Land",
|
||||
"state": "stat"
|
||||
},
|
||||
"description": "Bruk AirVisual cloud API til \u00e5 overv\u00e5ke en by/stat/land.",
|
||||
"title": "Konfigurer en Geography"
|
||||
},
|
||||
"node_pro": {
|
||||
"data": {
|
||||
"ip_address": "Vert",
|
||||
|
@ -7,7 +7,8 @@
|
||||
"error": {
|
||||
"cannot_connect": "Nie mo\u017cna nawi\u0105za\u0107 po\u0142\u0105czenia",
|
||||
"general_error": "Nieoczekiwany b\u0142\u0105d",
|
||||
"invalid_api_key": "Nieprawid\u0142owy klucz API"
|
||||
"invalid_api_key": "Nieprawid\u0142owy klucz API",
|
||||
"location_not_found": "Nie znaleziono lokalizacji"
|
||||
},
|
||||
"step": {
|
||||
"geography": {
|
||||
@ -19,6 +20,25 @@
|
||||
"description": "U\u017cyj interfejsu API chmury AirVisual do monitorowania lokalizacji geograficznej.",
|
||||
"title": "Konfiguracja Geography"
|
||||
},
|
||||
"geography_by_coords": {
|
||||
"data": {
|
||||
"api_key": "Klucz API",
|
||||
"latitude": "Szeroko\u015b\u0107 geograficzna",
|
||||
"longitude": "D\u0142ugo\u015b\u0107 geograficzna"
|
||||
},
|
||||
"description": "U\u017cyj API chmury AirVisual do monitorowania szeroko\u015bci/d\u0142ugo\u015bci geograficznej.",
|
||||
"title": "Konfiguracja Geography"
|
||||
},
|
||||
"geography_by_name": {
|
||||
"data": {
|
||||
"api_key": "Klucz API",
|
||||
"city": "Miasto",
|
||||
"country": "Kraj",
|
||||
"state": "Stan"
|
||||
},
|
||||
"description": "U\u017cyj API chmury AirVisual do monitorowania miasta/stanu/kraju.",
|
||||
"title": "Konfiguracja Geography"
|
||||
},
|
||||
"node_pro": {
|
||||
"data": {
|
||||
"ip_address": "Nazwa hosta lub adres IP",
|
||||
|
@ -1,7 +1,8 @@
|
||||
{
|
||||
"config": {
|
||||
"error": {
|
||||
"general_error": "Ett ok\u00e4nt fel intr\u00e4ffade."
|
||||
"general_error": "Ett ok\u00e4nt fel intr\u00e4ffade.",
|
||||
"invalid_api_key": "Ogiltig API-nyckel"
|
||||
},
|
||||
"step": {
|
||||
"geography": {
|
||||
|
59
homeassistant/components/airvisual/translations/tr.json
Normal file
59
homeassistant/components/airvisual/translations/tr.json
Normal file
@ -0,0 +1,59 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"reauth_successful": "Yeniden kimlik do\u011frulama ba\u015far\u0131l\u0131 oldu"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Ba\u011flanma hatas\u0131",
|
||||
"general_error": "Beklenmeyen hata",
|
||||
"invalid_api_key": "Ge\u00e7ersiz API anahtar\u0131",
|
||||
"location_not_found": "Konum bulunamad\u0131"
|
||||
},
|
||||
"step": {
|
||||
"geography": {
|
||||
"data": {
|
||||
"api_key": "API Anahtar\u0131",
|
||||
"latitude": "Enlem",
|
||||
"longitude": "Boylam"
|
||||
}
|
||||
},
|
||||
"geography_by_coords": {
|
||||
"data": {
|
||||
"api_key": "API Anahtar\u0131",
|
||||
"latitude": "Enlem",
|
||||
"longitude": "Boylam"
|
||||
},
|
||||
"description": "Bir enlem / boylam\u0131 izlemek i\u00e7in AirVisual bulut API'sini kullan\u0131n.",
|
||||
"title": "Bir Co\u011frafyay\u0131 Yap\u0131land\u0131rma"
|
||||
},
|
||||
"geography_by_name": {
|
||||
"data": {
|
||||
"api_key": "API Anahtar\u0131",
|
||||
"city": "\u015eehir",
|
||||
"country": "\u00dclke",
|
||||
"state": "durum"
|
||||
},
|
||||
"title": "Bir Co\u011frafyay\u0131 Yap\u0131land\u0131rma"
|
||||
},
|
||||
"node_pro": {
|
||||
"data": {
|
||||
"ip_address": "Ana Bilgisayar",
|
||||
"password": "Parola"
|
||||
},
|
||||
"description": "Ki\u015fisel bir AirVisual \u00fcnitesini izleyin. Parola, \u00fcnitenin kullan\u0131c\u0131 aray\u00fcz\u00fcnden al\u0131nabilir."
|
||||
},
|
||||
"reauth_confirm": {
|
||||
"data": {
|
||||
"api_key": "API Anahtar\u0131"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"init": {
|
||||
"title": "AirVisual'\u0131 yap\u0131land\u0131r\u0131n"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
57
homeassistant/components/airvisual/translations/uk.json
Normal file
57
homeassistant/components/airvisual/translations/uk.json
Normal file
@ -0,0 +1,57 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u0434\u043b\u044f \u0446\u044c\u043e\u0433\u043e \u043c\u0456\u0441\u0446\u0435\u0437\u043d\u0430\u0445\u043e\u0434\u0436\u0435\u043d\u043d\u044f \u0432\u0436\u0435 \u0432\u0438\u043a\u043e\u043d\u0430\u043d\u0435. \u0410\u0431\u043e \u0446\u0435\u0439 Node / Pro ID \u0432\u0436\u0435 \u0437\u0430\u0440\u0435\u0454\u0441\u0442\u0440\u043e\u0432\u0430\u043d\u0438\u0439.",
|
||||
"reauth_successful": "\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u0430 \u0430\u0432\u0442\u0435\u043d\u0442\u0438\u0444\u0456\u043a\u0430\u0446\u0456\u044f \u043f\u0440\u043e\u0439\u0448\u043b\u0430 \u0443\u0441\u043f\u0456\u0448\u043d\u043e"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "\u041d\u0435 \u0432\u0434\u0430\u043b\u043e\u0441\u044f \u043f\u0456\u0434'\u0454\u0434\u043d\u0430\u0442\u0438\u0441\u044f",
|
||||
"general_error": "\u041d\u0435\u043e\u0447\u0456\u043a\u0443\u0432\u0430\u043d\u0430 \u043f\u043e\u043c\u0438\u043b\u043a\u0430",
|
||||
"invalid_api_key": "\u0425\u0438\u0431\u043d\u0438\u0439 \u043a\u043b\u044e\u0447 API"
|
||||
},
|
||||
"step": {
|
||||
"geography": {
|
||||
"data": {
|
||||
"api_key": "\u041a\u043b\u044e\u0447 API",
|
||||
"latitude": "\u0428\u0438\u0440\u043e\u0442\u0430",
|
||||
"longitude": "\u0414\u043e\u0432\u0433\u043e\u0442\u0430"
|
||||
},
|
||||
"description": "\u041c\u043e\u043d\u0456\u0442\u043e\u0440\u0438\u043d\u0433 \u043c\u0456\u0441\u0446\u0435\u0437\u043d\u0430\u0445\u043e\u0434\u0436\u0435\u043d\u043d\u044f \u0437\u0430 \u0434\u043e\u043f\u043e\u043c\u043e\u0433\u043e\u044e \u0445\u043c\u0430\u0440\u043d\u043e\u0433\u043e API AirVisual.",
|
||||
"title": "\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f \u043c\u0456\u0441\u0446\u0435\u0437\u043d\u0430\u0445\u043e\u0434\u0436\u0435\u043d\u043d\u044f"
|
||||
},
|
||||
"node_pro": {
|
||||
"data": {
|
||||
"ip_address": "\u0425\u043e\u0441\u0442",
|
||||
"password": "\u041f\u0430\u0440\u043e\u043b\u044c"
|
||||
},
|
||||
"description": "\u041c\u043e\u043d\u0456\u0442\u043e\u0440\u0438\u043d\u0433 \u043f\u0440\u0438\u0441\u0442\u0440\u043e\u044e AirVisual. \u041f\u0430\u0440\u043e\u043b\u044c \u043c\u043e\u0436\u043d\u0430 \u043e\u0442\u0440\u0438\u043c\u0430\u0442\u0438 \u0432 \u0456\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0456 \u043f\u0440\u0438\u0441\u0442\u0440\u043e\u0457\u0432.",
|
||||
"title": "\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f AirVisual Node / Pro"
|
||||
},
|
||||
"reauth_confirm": {
|
||||
"data": {
|
||||
"api_key": "\u041a\u043b\u044e\u0447 API"
|
||||
},
|
||||
"title": "\u041f\u043e\u0432\u0442\u043e\u0440\u043d\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0456\u043a\u0430\u0446\u0456\u044f \u043f\u0440\u043e\u0444\u0456\u043b\u044e"
|
||||
},
|
||||
"user": {
|
||||
"data": {
|
||||
"cloud_api": "\u041c\u0456\u0441\u0446\u0435\u0437\u043d\u0430\u0445\u043e\u0434\u0436\u0435\u043d\u043d\u044f",
|
||||
"node_pro": "AirVisual Node Pro",
|
||||
"type": "\u0422\u0438\u043f \u0456\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0456\u0457"
|
||||
},
|
||||
"description": "\u0412\u0438\u0431\u0435\u0440\u0456\u0442\u044c \u0442\u0438\u043f \u0434\u0430\u043d\u0438\u0445 AirVisual, \u044f\u043a\u0438\u0439 \u0412\u0438 \u0445\u043e\u0447\u0435\u0442\u0435 \u0432\u0456\u0434\u0441\u0442\u0435\u0436\u0443\u0432\u0430\u0442\u0438.",
|
||||
"title": "AirVisual"
|
||||
}
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"init": {
|
||||
"data": {
|
||||
"show_on_map": "\u041f\u043e\u043a\u0430\u0437\u0443\u0432\u0430\u0442\u0438 \u0432\u0456\u0434\u0441\u0442\u0435\u0436\u0443\u0432\u0430\u043d\u0443 \u043e\u0431\u043b\u0430\u0441\u0442\u044c \u043d\u0430 \u043a\u0430\u0440\u0442\u0456"
|
||||
},
|
||||
"title": "\u041d\u0430\u043b\u0430\u0448\u0442\u0443\u0432\u0430\u043d\u043d\u044f AirVisual"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -7,7 +7,8 @@
|
||||
"error": {
|
||||
"cannot_connect": "\u9023\u7dda\u5931\u6557",
|
||||
"general_error": "\u672a\u9810\u671f\u932f\u8aa4",
|
||||
"invalid_api_key": "API \u5bc6\u9470\u7121\u6548"
|
||||
"invalid_api_key": "API \u5bc6\u9470\u7121\u6548",
|
||||
"location_not_found": "\u627e\u4e0d\u5230\u5730\u9ede"
|
||||
},
|
||||
"step": {
|
||||
"geography": {
|
||||
@ -19,6 +20,25 @@
|
||||
"description": "\u4f7f\u7528 AirVisual \u96f2\u7aef API \u4ee5\u76e3\u63a7\u5730\u7406\u5ea7\u6a19\u3002",
|
||||
"title": "\u8a2d\u5b9a\u5730\u7406\u5ea7\u6a19"
|
||||
},
|
||||
"geography_by_coords": {
|
||||
"data": {
|
||||
"api_key": "API \u5bc6\u9470",
|
||||
"latitude": "\u7def\u5ea6",
|
||||
"longitude": "\u7d93\u5ea6"
|
||||
},
|
||||
"description": "\u4f7f\u7528 AirVisual \u96f2\u7aef API \u4ee5\u76e3\u63a7\u7d93\u5ea6/\u7def\u5ea6\u3002",
|
||||
"title": "\u8a2d\u5b9a\u5730\u7406\u5ea7\u6a19"
|
||||
},
|
||||
"geography_by_name": {
|
||||
"data": {
|
||||
"api_key": "API \u5bc6\u9470",
|
||||
"city": "\u57ce\u5e02",
|
||||
"country": "\u570b\u5bb6",
|
||||
"state": "\u5dde"
|
||||
},
|
||||
"description": "\u4f7f\u7528 AirVisual \u96f2\u7aef API \u4ee5\u76e3\u63a7\u57ce\u5e02/\u5dde/\u570b\u5bb6\u3002",
|
||||
"title": "\u8a2d\u5b9a\u5730\u7406\u5ea7\u6a19"
|
||||
},
|
||||
"node_pro": {
|
||||
"data": {
|
||||
"ip_address": "\u4e3b\u6a5f\u7aef",
|
||||
|
@ -23,7 +23,6 @@ from homeassistant.const import (
|
||||
STATE_ALARM_ARMED_NIGHT,
|
||||
STATE_ALARM_ARMING,
|
||||
STATE_ALARM_DISARMED,
|
||||
STATE_ALARM_PENDING,
|
||||
STATE_ALARM_TRIGGERED,
|
||||
)
|
||||
from homeassistant.core import CALLBACK_TYPE, HomeAssistant
|
||||
@ -143,13 +142,10 @@ async def async_attach_trigger(
|
||||
from_state = STATE_ALARM_DISARMED
|
||||
to_state = STATE_ALARM_ARMING
|
||||
elif config[CONF_TYPE] == "armed_home":
|
||||
from_state = STATE_ALARM_PENDING or STATE_ALARM_ARMING
|
||||
to_state = STATE_ALARM_ARMED_HOME
|
||||
elif config[CONF_TYPE] == "armed_away":
|
||||
from_state = STATE_ALARM_PENDING or STATE_ALARM_ARMING
|
||||
to_state = STATE_ALARM_ARMED_AWAY
|
||||
elif config[CONF_TYPE] == "armed_night":
|
||||
from_state = STATE_ALARM_PENDING or STATE_ALARM_ARMING
|
||||
to_state = STATE_ALARM_ARMED_NIGHT
|
||||
|
||||
state_config = {
|
||||
|
@ -1,4 +1,10 @@
|
||||
{
|
||||
"device_automation": {
|
||||
"trigger_type": {
|
||||
"disarmed": "{entity_name} b\u0131rak\u0131ld\u0131",
|
||||
"triggered": "{entity_name} tetiklendi"
|
||||
}
|
||||
},
|
||||
"state": {
|
||||
"_": {
|
||||
"armed": "Etkin",
|
||||
|
@ -1,13 +1,36 @@
|
||||
{
|
||||
"device_automation": {
|
||||
"action_type": {
|
||||
"arm_away": "\u0423\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u0440\u0435\u0436\u0438\u043c \u043e\u0445\u043e\u0440\u043e\u043d\u0438 \"\u041d\u0435 \u0432\u0434\u043e\u043c\u0430\" \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u0456 {entity_name}",
|
||||
"arm_home": "\u0423\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u0440\u0435\u0436\u0438\u043c \u043e\u0445\u043e\u0440\u043e\u043d\u0438 \"\u0412\u0434\u043e\u043c\u0430\" \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u0456 {entity_name}",
|
||||
"arm_night": "\u0423\u0432\u0456\u043c\u043a\u043d\u0443\u0442\u0438 \u0440\u0435\u0436\u0438\u043c \u043e\u0445\u043e\u0440\u043e\u043d\u0438 \"\u041d\u0456\u0447\" \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u0456 {entity_name}",
|
||||
"disarm": "\u0412\u0456\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u0438 \u043e\u0445\u043e\u0440\u043e\u043d\u0443 \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u0456 {entity_name}",
|
||||
"trigger": "{entity_name} \u0441\u043f\u0440\u0430\u0446\u044c\u043e\u0432\u0443\u0454"
|
||||
},
|
||||
"condition_type": {
|
||||
"is_armed_away": "\u0423\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u0438\u0439 \u0440\u0435\u0436\u0438\u043c \u043e\u0445\u043e\u0440\u043e\u043d\u0438 \"\u041d\u0435 \u0432\u0434\u043e\u043c\u0430\" \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u0456 {entity_name}",
|
||||
"is_armed_home": "\u0423\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u0438\u0439 \u0440\u0435\u0436\u0438\u043c \u043e\u0445\u043e\u0440\u043e\u043d\u0438 \"\u0412\u0434\u043e\u043c\u0430\" \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u0456 {entity_name}",
|
||||
"is_armed_night": "\u0423\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u0438\u0439 \u0440\u0435\u0436\u0438\u043c \u043e\u0445\u043e\u0440\u043e\u043d\u0438 \"\u041d\u0456\u0447\" \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u0456 {entity_name}",
|
||||
"is_disarmed": "\u0412\u0438\u043c\u043a\u043d\u0435\u043d\u0430 \u043e\u0445\u043e\u0440\u043e\u043d\u0430 \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u0456 {entity_name}",
|
||||
"is_triggered": "{entity_name} \u0441\u043f\u0440\u0430\u0446\u044c\u043e\u0432\u0443\u0454"
|
||||
},
|
||||
"trigger_type": {
|
||||
"armed_away": "\u0423\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u0438\u0439 \u0440\u0435\u0436\u0438\u043c \u043e\u0445\u043e\u0440\u043e\u043d\u0438 \"\u041d\u0435 \u0432\u0434\u043e\u043c\u0430\" \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u0456 {entity_name}",
|
||||
"armed_home": "\u0423\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u0438\u0439 \u0440\u0435\u0436\u0438\u043c \u043e\u0445\u043e\u0440\u043e\u043d\u0438 \"\u0412\u0434\u043e\u043c\u0430\" \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u0456 {entity_name}",
|
||||
"armed_night": "\u0423\u0432\u0456\u043c\u043a\u043d\u0435\u043d\u0438\u0439 \u0440\u0435\u0436\u0438\u043c \u043e\u0445\u043e\u0440\u043e\u043d\u0438 \"\u041d\u0456\u0447\" \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u0456 {entity_name}",
|
||||
"disarmed": "\u0412\u0438\u043c\u043a\u043d\u0435\u043d\u0430 \u043e\u0445\u043e\u0440\u043e\u043d\u0430 \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u0456 {entity_name}",
|
||||
"triggered": "{entity_name} \u0441\u043f\u0440\u0430\u0446\u044c\u043e\u0432\u0443\u0454"
|
||||
}
|
||||
},
|
||||
"state": {
|
||||
"_": {
|
||||
"armed": "\u041e\u0445\u043e\u0440\u043e\u043d\u0430",
|
||||
"armed_away": "\u041e\u0445\u043e\u0440\u043e\u043d\u0430 (\u043d\u0435 \u0432\u0434\u043e\u043c\u0430)",
|
||||
"armed_away": "\u041e\u0445\u043e\u0440\u043e\u043d\u0430 (\u041d\u0435 \u0432\u0434\u043e\u043c\u0430)",
|
||||
"armed_custom_bypass": "\u041e\u0445\u043e\u0440\u043e\u043d\u0430 \u0437 \u0432\u0438\u043d\u044f\u0442\u043a\u0430\u043c\u0438",
|
||||
"armed_home": "\u0411\u0443\u0434\u0438\u043d\u043a\u043e\u0432\u0430 \u043e\u0445\u043e\u0440\u043e\u043d\u0430",
|
||||
"armed_home": "\u041e\u0445\u043e\u0440\u043e\u043d\u0430 (\u0412\u0434\u043e\u043c\u0430)",
|
||||
"armed_night": "\u041d\u0456\u0447\u043d\u0430 \u043e\u0445\u043e\u0440\u043e\u043d\u0430",
|
||||
"arming": "\u0421\u0442\u0430\u0432\u043b\u044e \u043d\u0430 \u043e\u0445\u043e\u0440\u043e\u043d\u0443",
|
||||
"disarmed": "\u0417\u043d\u044f\u0442\u043e",
|
||||
"disarmed": "\u0417\u043d\u044f\u0442\u043e \u0437 \u043e\u0445\u043e\u0440\u043e\u043d\u0438",
|
||||
"disarming": "\u0417\u043d\u044f\u0442\u0442\u044f",
|
||||
"pending": "\u041e\u0447\u0456\u043a\u0443\u044e",
|
||||
"triggered": "\u0422\u0440\u0438\u0432\u043e\u0433\u0430"
|
||||
|
@ -1,7 +1,10 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Ger\u00e4t ist bereits konfiguriert"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Verbindungsfehler"
|
||||
"cannot_connect": "Verbindung fehlgeschlagen"
|
||||
},
|
||||
"step": {
|
||||
"protocol": {
|
||||
@ -42,7 +45,7 @@
|
||||
"data": {
|
||||
"zone_number": "Zonennummer"
|
||||
},
|
||||
"description": "Geben Sie die Zonennummer ein, die Sie hinzuf\u00fcgen, bearbeiten oder entfernen m\u00f6chten."
|
||||
"description": "Gib die die Zonennummer ein, die du hinzuf\u00fcgen, bearbeiten oder entfernen m\u00f6chtest."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
48
homeassistant/components/alarmdecoder/translations/tr.json
Normal file
48
homeassistant/components/alarmdecoder/translations/tr.json
Normal file
@ -0,0 +1,48 @@
|
||||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Cihaz zaten yap\u0131land\u0131r\u0131lm\u0131\u015f"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Ba\u011flanma hatas\u0131"
|
||||
},
|
||||
"step": {
|
||||
"protocol": {
|
||||
"data": {
|
||||
"host": "Ana Bilgisayar",
|
||||
"port": "Port"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"error": {
|
||||
"relay_inclusive": "R\u00f6le Adresi ve R\u00f6le Kanal\u0131 birbirine ba\u011fl\u0131d\u0131r ve birlikte eklenmelidir."
|
||||
},
|
||||
"step": {
|
||||
"arm_settings": {
|
||||
"data": {
|
||||
"alt_night_mode": "Alternatif Gece Modu"
|
||||
}
|
||||
},
|
||||
"init": {
|
||||
"data": {
|
||||
"edit_select": "D\u00fczenle"
|
||||
}
|
||||
},
|
||||
"zone_details": {
|
||||
"data": {
|
||||
"zone_name": "B\u00f6lge Ad\u0131",
|
||||
"zone_relayaddr": "R\u00f6le Adresi",
|
||||
"zone_relaychan": "R\u00f6le Kanal\u0131"
|
||||
}
|
||||
},
|
||||
"zone_select": {
|
||||
"data": {
|
||||
"zone_number": "B\u00f6lge Numaras\u0131"
|
||||
},
|
||||
"title": "AlarmDecoder'\u0131 yap\u0131land\u0131r\u0131n"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
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