Merge pull request #42516 from home-assistant/rc
This commit is contained in:
commit
9c0a2d69ff
4273 changed files with 62799 additions and 27146 deletions
31
.coveragerc
31
.coveragerc
|
@ -98,9 +98,6 @@ omit =
|
|||
homeassistant/components/bme680/sensor.py
|
||||
homeassistant/components/bmp280/sensor.py
|
||||
homeassistant/components/bmw_connected_drive/*
|
||||
homeassistant/components/bom/camera.py
|
||||
homeassistant/components/bom/sensor.py
|
||||
homeassistant/components/bom/weather.py
|
||||
homeassistant/components/braviatv/__init__.py
|
||||
homeassistant/components/braviatv/const.py
|
||||
homeassistant/components/braviatv/media_player.py
|
||||
|
@ -134,7 +131,6 @@ omit =
|
|||
homeassistant/components/clickatell/notify.py
|
||||
homeassistant/components/clicksend/notify.py
|
||||
homeassistant/components/clicksend_tts/notify.py
|
||||
homeassistant/components/cloudflare/*
|
||||
homeassistant/components/cmus/media_player.py
|
||||
homeassistant/components/co2signal/*
|
||||
homeassistant/components/coinbase/*
|
||||
|
@ -609,8 +605,6 @@ omit =
|
|||
homeassistant/components/omnilogic/__init__.py
|
||||
homeassistant/components/omnilogic/common.py
|
||||
homeassistant/components/omnilogic/sensor.py
|
||||
homeassistant/components/onewire/const.py
|
||||
homeassistant/components/onewire/sensor.py
|
||||
homeassistant/components/onkyo/media_player.py
|
||||
homeassistant/components/onvif/__init__.py
|
||||
homeassistant/components/onvif/base.py
|
||||
|
@ -651,6 +645,9 @@ omit =
|
|||
homeassistant/components/ovo_energy/__init__.py
|
||||
homeassistant/components/ovo_energy/const.py
|
||||
homeassistant/components/ovo_energy/sensor.py
|
||||
homeassistant/components/ozw/__init__.py
|
||||
homeassistant/components/ozw/entity.py
|
||||
homeassistant/components/ozw/services.py
|
||||
homeassistant/components/panasonic_bluray/media_player.py
|
||||
homeassistant/components/panasonic_viera/media_player.py
|
||||
homeassistant/components/pandora/media_player.py
|
||||
|
@ -720,7 +717,6 @@ omit =
|
|||
homeassistant/components/repetier/__init__.py
|
||||
homeassistant/components/repetier/sensor.py
|
||||
homeassistant/components/remote_rpi_gpio/*
|
||||
homeassistant/components/rest/binary_sensor.py
|
||||
homeassistant/components/rest/notify.py
|
||||
homeassistant/components/rest/switch.py
|
||||
homeassistant/components/ring/camera.py
|
||||
|
@ -779,7 +775,9 @@ omit =
|
|||
homeassistant/components/simplepush/notify.py
|
||||
homeassistant/components/simplisafe/__init__.py
|
||||
homeassistant/components/simplisafe/alarm_control_panel.py
|
||||
homeassistant/components/simplisafe/binary_sensor.py
|
||||
homeassistant/components/simplisafe/lock.py
|
||||
homeassistant/components/simplisafe/sensor.py
|
||||
homeassistant/components/simulated/sensor.py
|
||||
homeassistant/components/sisyphus/*
|
||||
homeassistant/components/sky_hub/*
|
||||
|
@ -823,6 +821,7 @@ omit =
|
|||
homeassistant/components/spotify/__init__.py
|
||||
homeassistant/components/spotify/media_player.py
|
||||
homeassistant/components/squeezebox/__init__.py
|
||||
homeassistant/components/squeezebox/browse_media.py
|
||||
homeassistant/components/squeezebox/media_player.py
|
||||
homeassistant/components/starline/*
|
||||
homeassistant/components/starlingbank/sensor.py
|
||||
|
@ -912,6 +911,7 @@ omit =
|
|||
homeassistant/components/torque/sensor.py
|
||||
homeassistant/components/totalconnect/*
|
||||
homeassistant/components/touchline/climate.py
|
||||
homeassistant/components/tplink/common.py
|
||||
homeassistant/components/tplink/switch.py
|
||||
homeassistant/components/tplink_lte/*
|
||||
homeassistant/components/traccar/device_tracker.py
|
||||
|
@ -942,7 +942,9 @@ omit =
|
|||
homeassistant/components/upb/const.py
|
||||
homeassistant/components/upb/light.py
|
||||
homeassistant/components/upb/scene.py
|
||||
homeassistant/components/upcloud/*
|
||||
homeassistant/components/upcloud/__init__.py
|
||||
homeassistant/components/upcloud/binary_sensor.py
|
||||
homeassistant/components/upcloud/switch.py
|
||||
homeassistant/components/upnp/*
|
||||
homeassistant/components/upc_connect/*
|
||||
homeassistant/components/uptimerobot/binary_sensor.py
|
||||
|
@ -976,6 +978,7 @@ omit =
|
|||
homeassistant/components/vlc_telnet/media_player.py
|
||||
homeassistant/components/volkszaehler/sensor.py
|
||||
homeassistant/components/volumio/__init__.py
|
||||
homeassistant/components/volumio/browse_media.py
|
||||
homeassistant/components/volumio/media_player.py
|
||||
homeassistant/components/volvooncall/*
|
||||
homeassistant/components/w800rf32/*
|
||||
|
@ -996,6 +999,15 @@ omit =
|
|||
homeassistant/components/worldtidesinfo/sensor.py
|
||||
homeassistant/components/worxlandroid/sensor.py
|
||||
homeassistant/components/x10/light.py
|
||||
homeassistant/components/xbox/__init__.py
|
||||
homeassistant/components/xbox/api.py
|
||||
homeassistant/components/xbox/base_sensor.py
|
||||
homeassistant/components/xbox/binary_sensor.py
|
||||
homeassistant/components/xbox/browse_media.py
|
||||
homeassistant/components/xbox/media_player.py
|
||||
homeassistant/components/xbox/media_source.py
|
||||
homeassistant/components/xbox/remote.py
|
||||
homeassistant/components/xbox/sensor.py
|
||||
homeassistant/components/xbox_live/sensor.py
|
||||
homeassistant/components/xeoma/camera.py
|
||||
homeassistant/components/xfinity/device_tracker.py
|
||||
|
@ -1053,9 +1065,6 @@ omit =
|
|||
homeassistant/components/zoneminder/*
|
||||
homeassistant/components/supla/*
|
||||
homeassistant/components/zwave/util.py
|
||||
homeassistant/components/ozw/__init__.py
|
||||
homeassistant/components/ozw/entity.py
|
||||
homeassistant/components/ozw/services.py
|
||||
|
||||
[report]
|
||||
# Regexes for lines to exclude from consideration
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"appPort": 8123,
|
||||
"runArgs": ["-e", "GIT_EDITOR=code --wait"],
|
||||
"extensions": [
|
||||
"ms-python.python",
|
||||
"ms-python.vscode-pylance",
|
||||
"visualstudioexptteam.vscodeintellicode",
|
||||
"ms-azure-devops.azure-pipelines",
|
||||
"redhat.vscode-yaml",
|
||||
|
|
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
2
.github/PULL_REQUEST_TEMPLATE.md
vendored
|
@ -119,7 +119,7 @@ To help with the load of incoming pull requests:
|
|||
|
||||
- [ ] I have reviewed two other [open pull requests][prs] in this repository.
|
||||
|
||||
[prs]: https://github.com/home-assistant/core/pulls?q=is%3Aopen+is%3Apr+-author%3A%40me+-draft%3Atrue+-label%3Awaiting-for-upstream+sort%3Acreated-asc+-review%3Aapproved
|
||||
[prs]: https://github.com/home-assistant/core/pulls?q=is%3Aopen+is%3Apr+-author%3A%40me+-draft%3Atrue+-label%3Awaiting-for-upstream+sort%3Acreated-desc+review%3Anone
|
||||
|
||||
<!--
|
||||
Thank you for contributing <3
|
||||
|
|
26
.github/workflows/ci.yaml
vendored
26
.github/workflows/ci.yaml
vendored
|
@ -25,7 +25,7 @@ jobs:
|
|||
uses: actions/checkout@v2
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
id: python
|
||||
uses: actions/setup-python@v2.1.2
|
||||
uses: actions/setup-python@v2.1.4
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
- name: Restore base Python virtual environment
|
||||
|
@ -73,7 +73,7 @@ jobs:
|
|||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
uses: actions/setup-python@v2.1.2
|
||||
uses: actions/setup-python@v2.1.4
|
||||
id: python
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
|
@ -118,7 +118,7 @@ jobs:
|
|||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
uses: actions/setup-python@v2.1.2
|
||||
uses: actions/setup-python@v2.1.4
|
||||
id: python
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
|
@ -163,7 +163,7 @@ jobs:
|
|||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
uses: actions/setup-python@v2.1.2
|
||||
uses: actions/setup-python@v2.1.4
|
||||
id: python
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
|
@ -230,7 +230,7 @@ jobs:
|
|||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
uses: actions/setup-python@v2.1.2
|
||||
uses: actions/setup-python@v2.1.4
|
||||
id: python
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
|
@ -278,7 +278,7 @@ jobs:
|
|||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
uses: actions/setup-python@v2.1.2
|
||||
uses: actions/setup-python@v2.1.4
|
||||
id: python
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
|
@ -326,7 +326,7 @@ jobs:
|
|||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
uses: actions/setup-python@v2.1.2
|
||||
uses: actions/setup-python@v2.1.4
|
||||
id: python
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
|
@ -371,7 +371,7 @@ jobs:
|
|||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
uses: actions/setup-python@v2.1.2
|
||||
uses: actions/setup-python@v2.1.4
|
||||
id: python
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
|
@ -419,7 +419,7 @@ jobs:
|
|||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
uses: actions/setup-python@v2.1.2
|
||||
uses: actions/setup-python@v2.1.4
|
||||
id: python
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
|
@ -475,7 +475,7 @@ jobs:
|
|||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
uses: actions/setup-python@v2.1.2
|
||||
uses: actions/setup-python@v2.1.4
|
||||
id: python
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
|
@ -555,7 +555,7 @@ jobs:
|
|||
- name: Check out code from GitHub
|
||||
uses: actions/checkout@v2
|
||||
- name: Set up Python ${{ env.DEFAULT_PYTHON }}
|
||||
uses: actions/setup-python@v2.1.2
|
||||
uses: actions/setup-python@v2.1.4
|
||||
id: python
|
||||
with:
|
||||
python-version: ${{ env.DEFAULT_PYTHON }}
|
||||
|
@ -736,7 +736,7 @@ jobs:
|
|||
-p no:sugar \
|
||||
tests
|
||||
- name: Upload coverage artifact
|
||||
uses: actions/upload-artifact@v2.1.4
|
||||
uses: actions/upload-artifact@v2.2.0
|
||||
with:
|
||||
name: coverage-${{ matrix.python-version }}-group${{ matrix.group }}
|
||||
path: .coverage
|
||||
|
@ -779,4 +779,4 @@ jobs:
|
|||
coverage report --fail-under=94
|
||||
coverage xml
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v1.0.13
|
||||
uses: codecov/codecov-action@v1.0.14
|
||||
|
|
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -88,7 +88,7 @@ venv
|
|||
.venv
|
||||
Pipfile*
|
||||
share/*
|
||||
Scripts/
|
||||
/Scripts/
|
||||
|
||||
# vimmy stuff
|
||||
*.swp
|
||||
|
|
|
@ -22,7 +22,7 @@ repos:
|
|||
- --quiet-level=2
|
||||
exclude_types: [csv, json]
|
||||
- repo: https://gitlab.com/pycqa/flake8
|
||||
rev: 3.8.3
|
||||
rev: 3.8.4
|
||||
hooks:
|
||||
- id: flake8
|
||||
additional_dependencies:
|
||||
|
@ -87,5 +87,5 @@ repos:
|
|||
entry: script/run-in-env.sh python3 -m script.hassfest
|
||||
pass_filenames: false
|
||||
language: script
|
||||
types: [json]
|
||||
files: ^homeassistant/.+/(manifest|strings)\.json$
|
||||
types: [text]
|
||||
files: ^(homeassistant/.+/(manifest|strings)\.json|\.coveragerc)$
|
||||
|
|
21
CODEOWNERS
21
CODEOWNERS
|
@ -17,6 +17,7 @@ homeassistant/components/abode/* @shred86
|
|||
homeassistant/components/accuweather/* @bieniu
|
||||
homeassistant/components/acmeda/* @atmurray
|
||||
homeassistant/components/adguard/* @frenck
|
||||
homeassistant/components/advantage_air/* @Bre77
|
||||
homeassistant/components/agent_dvr/* @ispysoftware
|
||||
homeassistant/components/airly/* @bieniu
|
||||
homeassistant/components/airvisual/* @bachya
|
||||
|
@ -59,7 +60,6 @@ homeassistant/components/blebox/* @gadgetmobile
|
|||
homeassistant/components/blink/* @fronzbot
|
||||
homeassistant/components/bmp280/* @belidzs
|
||||
homeassistant/components/bmw_connected_drive/* @gerard33 @rikroe
|
||||
homeassistant/components/bom/* @maddenp
|
||||
homeassistant/components/bond/* @prystupa
|
||||
homeassistant/components/braviatv/* @bieniu
|
||||
homeassistant/components/broadlink/* @danielhiversen @felipediel
|
||||
|
@ -75,7 +75,7 @@ homeassistant/components/cisco_ios/* @fbradyirl
|
|||
homeassistant/components/cisco_mobility_express/* @fbradyirl
|
||||
homeassistant/components/cisco_webex_teams/* @fbradyirl
|
||||
homeassistant/components/cloud/* @home-assistant/cloud
|
||||
homeassistant/components/cloudflare/* @ludeeus
|
||||
homeassistant/components/cloudflare/* @ludeeus @ctalkington
|
||||
homeassistant/components/comfoconnect/* @michaelarnauts
|
||||
homeassistant/components/config/* @home-assistant/core
|
||||
homeassistant/components/configurator/* @home-assistant/core
|
||||
|
@ -161,8 +161,8 @@ homeassistant/components/goalzero/* @tkdrob
|
|||
homeassistant/components/gogogate2/* @vangorra
|
||||
homeassistant/components/google_assistant/* @home-assistant/cloud
|
||||
homeassistant/components/google_cloud/* @lufton
|
||||
homeassistant/components/google_translate/* @awarecan
|
||||
homeassistant/components/gpsd/* @fabaff
|
||||
homeassistant/components/gree/* @cmroche
|
||||
homeassistant/components/greeneye_monitor/* @jkeljo
|
||||
homeassistant/components/griddy/* @bdraco
|
||||
homeassistant/components/group/* @home-assistant/core
|
||||
|
@ -277,7 +277,7 @@ homeassistant/components/neato/* @dshokouhi @Santobert
|
|||
homeassistant/components/nederlandse_spoorwegen/* @YarmoM
|
||||
homeassistant/components/nello/* @pschmitt
|
||||
homeassistant/components/ness_alarm/* @nickw444
|
||||
homeassistant/components/nest/* @awarecan
|
||||
homeassistant/components/nest/* @awarecan @allenporter
|
||||
homeassistant/components/netatmo/* @cgtobi
|
||||
homeassistant/components/netdata/* @fabaff
|
||||
homeassistant/components/nexia/* @ryannazaretian @bdraco
|
||||
|
@ -305,7 +305,7 @@ homeassistant/components/ohmconnect/* @robbiet480
|
|||
homeassistant/components/ombi/* @larssont
|
||||
homeassistant/components/omnilogic/* @oliver84 @djtimca @gentoosu
|
||||
homeassistant/components/onboarding/* @home-assistant/core
|
||||
homeassistant/components/onewire/* @garbled1
|
||||
homeassistant/components/onewire/* @garbled1 @epenet
|
||||
homeassistant/components/onvif/* @hunterjm
|
||||
homeassistant/components/openerz/* @misialq
|
||||
homeassistant/components/opengarage/* @danielhiversen
|
||||
|
@ -317,7 +317,6 @@ homeassistant/components/orangepi_gpio/* @pascallj
|
|||
homeassistant/components/oru/* @bvlaicu
|
||||
homeassistant/components/ovo_energy/* @timmo001
|
||||
homeassistant/components/ozw/* @cgarwood @marcelveldt @MartinHjelmare
|
||||
homeassistant/components/panasonic_viera/* @joogps
|
||||
homeassistant/components/panel_custom/* @home-assistant/frontend
|
||||
homeassistant/components/panel_iframe/* @home-assistant/frontend
|
||||
homeassistant/components/pcal9535a/* @Shulyaka
|
||||
|
@ -334,6 +333,7 @@ homeassistant/components/plum_lightpad/* @ColinHarrington @prystupa
|
|||
homeassistant/components/point/* @fredrike
|
||||
homeassistant/components/poolsense/* @haemishkyd
|
||||
homeassistant/components/powerwall/* @bdraco @jrester
|
||||
homeassistant/components/profiler/* @bdraco
|
||||
homeassistant/components/progettihwsw/* @ardaseremet
|
||||
homeassistant/components/prometheus/* @knyar
|
||||
homeassistant/components/proxmoxve/* @k4ds3 @jhollowe
|
||||
|
@ -355,7 +355,7 @@ homeassistant/components/rainmachine/* @bachya
|
|||
homeassistant/components/random/* @fabaff
|
||||
homeassistant/components/rejseplanen/* @DarkFox
|
||||
homeassistant/components/repetier/* @MTrab
|
||||
homeassistant/components/rfxtrx/* @danielhiversen @elupus
|
||||
homeassistant/components/rfxtrx/* @danielhiversen @elupus @RobBie1221
|
||||
homeassistant/components/ring/* @balloob
|
||||
homeassistant/components/risco/* @OnFreund
|
||||
homeassistant/components/rmvtransport/* @cgtobi
|
||||
|
@ -363,6 +363,7 @@ homeassistant/components/roku/* @ctalkington
|
|||
homeassistant/components/roomba/* @pschmitt @cyr-ius @shenxn
|
||||
homeassistant/components/roon/* @pavoni
|
||||
homeassistant/components/rpi_power/* @shenxn @swetoast
|
||||
homeassistant/components/ruckus_unleashed/* @gabe565
|
||||
homeassistant/components/safe_mode/* @home-assistant/core
|
||||
homeassistant/components/saj/* @fredericvl
|
||||
homeassistant/components/salt/* @bjornorri
|
||||
|
@ -436,6 +437,7 @@ homeassistant/components/tado/* @michaelarnauts @bdraco
|
|||
homeassistant/components/tag/* @balloob @dmulcahey
|
||||
homeassistant/components/tahoma/* @philklei
|
||||
homeassistant/components/tankerkoenig/* @guillempages
|
||||
homeassistant/components/tasmota/* @emontnemery
|
||||
homeassistant/components/tautulli/* @ludeeus
|
||||
homeassistant/components/tellduslive/* @fredrike
|
||||
homeassistant/components/template/* @PhracturedBlue @tetienne
|
||||
|
@ -450,7 +452,7 @@ homeassistant/components/tmb/* @alemuro
|
|||
homeassistant/components/todoist/* @boralyl
|
||||
homeassistant/components/toon/* @frenck
|
||||
homeassistant/components/totalconnect/* @austinmroczek
|
||||
homeassistant/components/tplink/* @rytilahti
|
||||
homeassistant/components/tplink/* @rytilahti @thegardenmonkey
|
||||
homeassistant/components/traccar/* @ludeeus
|
||||
homeassistant/components/tradfri/* @ggravlingen
|
||||
homeassistant/components/trafikverket_train/* @endor-force
|
||||
|
@ -495,6 +497,7 @@ homeassistant/components/wled/* @frenck
|
|||
homeassistant/components/wolflink/* @adamkrol93
|
||||
homeassistant/components/workday/* @fabaff
|
||||
homeassistant/components/worldclock/* @fabaff
|
||||
homeassistant/components/xbox/* @hunterjm
|
||||
homeassistant/components/xbox_live/* @MartinHjelmare
|
||||
homeassistant/components/xfinity/* @cisasteelersfan
|
||||
homeassistant/components/xiaomi_aqara/* @danielhiversen @syssi
|
||||
|
@ -507,7 +510,7 @@ homeassistant/components/yeelight/* @rytilahti @zewelor @shenxn
|
|||
homeassistant/components/yeelightsunflower/* @lindsaymarkward
|
||||
homeassistant/components/yessssms/* @flowolf
|
||||
homeassistant/components/yi/* @bachya
|
||||
homeassistant/components/zeroconf/* @Kane610
|
||||
homeassistant/components/zeroconf/* @bdraco
|
||||
homeassistant/components/zerproc/* @emlove
|
||||
homeassistant/components/zha/* @dmulcahey @adminiuga
|
||||
homeassistant/components/zodiac/* @JulienTant
|
||||
|
|
|
@ -5,14 +5,14 @@ Everybody is invited and welcome to contribute to Home Assistant. There is a lot
|
|||
The process is straight-forward.
|
||||
|
||||
- Read [How to get faster PR reviews](https://github.com/kubernetes/community/blob/master/contributors/guide/pull-requests.md#best-practices-for-faster-reviews) by Kubernetes (but skip step 0 and 1)
|
||||
- Fork the Home Assistant [git repository](https://github.com/home-assistant/home-assistant).
|
||||
- Fork the Home Assistant [git repository](https://github.com/home-assistant/core).
|
||||
- Write the code for your device, notification service, sensor, or IoT thing.
|
||||
- Ensure tests work.
|
||||
- Create a Pull Request against the [**dev**](https://github.com/home-assistant/home-assistant/tree/dev) branch of Home Assistant.
|
||||
- Create a Pull Request against the [**dev**](https://github.com/home-assistant/core/tree/dev) branch of Home Assistant.
|
||||
|
||||
Still interested? Then you should take a peek at the [developer documentation](https://developers.home-assistant.io/) to get more details.
|
||||
|
||||
## Feature suggestions
|
||||
|
||||
If you want to suggest a new feature for Home Assistant (e.g., new integrations), please open a thread in our [Community Forum: Feature Requests](https://community.home-assistant.io/c/feature-requests).
|
||||
We use [GitHub for tracking issues](https://github.com/home-assistant/home-assistant/issues), not for tracking feature requests.
|
||||
We use [GitHub for tracking issues](https://github.com/home-assistant/core/issues), not for tracking feature requests.
|
||||
|
|
|
@ -143,8 +143,8 @@ stages:
|
|||
|
||||
version="$(homeassistantRelease)"
|
||||
|
||||
git clone https://github.com/home-assistant/hassio-version
|
||||
cd hassio-version
|
||||
git clone https://github.com/home-assistant/version
|
||||
cd version
|
||||
|
||||
dev_version="$(jq --raw-output '.homeassistant.default' dev.json)"
|
||||
beta_version="$(jq --raw-output '.homeassistant.default' beta.json)"
|
||||
|
|
10
build.json
10
build.json
|
@ -1,11 +1,11 @@
|
|||
{
|
||||
"image": "homeassistant/{arch}-homeassistant",
|
||||
"build_from": {
|
||||
"aarch64": "homeassistant/aarch64-homeassistant-base:8.4.0",
|
||||
"armhf": "homeassistant/armhf-homeassistant-base:8.4.0",
|
||||
"armv7": "homeassistant/armv7-homeassistant-base:8.4.0",
|
||||
"amd64": "homeassistant/amd64-homeassistant-base:8.4.0",
|
||||
"i386": "homeassistant/i386-homeassistant-base:8.4.0"
|
||||
"aarch64": "homeassistant/aarch64-homeassistant-base:2020.10.0",
|
||||
"armhf": "homeassistant/armhf-homeassistant-base:2020.10.0",
|
||||
"armv7": "homeassistant/armv7-homeassistant-base:2020.10.0",
|
||||
"amd64": "homeassistant/amd64-homeassistant-base:2020.10.0",
|
||||
"i386": "homeassistant/i386-homeassistant-base:2020.10.0"
|
||||
},
|
||||
"labels": {
|
||||
"io.hass.type": "core"
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 102 KiB |
|
@ -1,6 +1,6 @@
|
|||
<ul>
|
||||
<li><a href="https://home-assistant.io/">Homepage</a></li>
|
||||
<li><a href="https://community.home-assistant.io">Community Forums</a></li>
|
||||
<li><a href="https://github.com/home-assistant/home-assistant">GitHub</a></li>
|
||||
<li><a href="https://github.com/home-assistant/core">GitHub</a></li>
|
||||
<li><a href="https://discord.gg/c5DvZ4e">Discord</a></li>
|
||||
</ul>
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
import asyncio
|
||||
from collections import OrderedDict
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
from typing import Any, Dict, List, Optional, Tuple, cast
|
||||
|
||||
import jwt
|
||||
|
@ -20,7 +19,6 @@ from .providers import AuthProvider, LoginFlow, auth_provider_from_config
|
|||
EVENT_USER_ADDED = "user_added"
|
||||
EVENT_USER_REMOVED = "user_removed"
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
_MfaModuleDict = Dict[str, MultiFactorAuthModule]
|
||||
_ProviderKey = Tuple[str, Optional[str]]
|
||||
_ProviderDict = Dict[_ProviderKey, AuthProvider]
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
"""Example auth module."""
|
||||
import logging
|
||||
from typing import Any, Dict
|
||||
|
||||
import voluptuous as vol
|
||||
|
@ -22,8 +21,6 @@ CONFIG_SCHEMA = MULTI_FACTOR_AUTH_MODULE_SCHEMA.extend(
|
|||
extra=vol.PREVENT_EXTRA,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@MULTI_FACTOR_AUTH_MODULES.register("insecure_example")
|
||||
class InsecureExampleModule(MultiFactorAuthModule):
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
"""Time-based One Time Password auth module."""
|
||||
import asyncio
|
||||
from io import BytesIO
|
||||
import logging
|
||||
from typing import Any, Dict, Optional, Tuple
|
||||
|
||||
import voluptuous as vol
|
||||
|
@ -30,8 +29,6 @@ INPUT_FIELD_CODE = "code"
|
|||
|
||||
DUMMY_SECRET = "FPPTH34D4E3MI2HG"
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def _generate_qr_code(data: str) -> str:
|
||||
"""Generate a base64 PNG string represent QR Code image of data."""
|
||||
|
|
|
@ -47,8 +47,8 @@ class AbodeFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
except (AbodeException, ConnectTimeout, HTTPError) as ex:
|
||||
LOGGER.error("Unable to connect to Abode: %s", str(ex))
|
||||
if ex.errcode == HTTP_BAD_REQUEST:
|
||||
return self._show_form({"base": "invalid_credentials"})
|
||||
return self._show_form({"base": "connection_error"})
|
||||
return self._show_form({"base": "invalid_auth"})
|
||||
return self._show_form({"base": "cannot_connect"})
|
||||
|
||||
return self.async_create_entry(
|
||||
title=user_input[CONF_USERNAME],
|
||||
|
|
|
@ -10,12 +10,11 @@
|
|||
}
|
||||
},
|
||||
"error": {
|
||||
"identifier_exists": "Account already registered.",
|
||||
"invalid_credentials": "Invalid credentials.",
|
||||
"connection_error": "Unable to connect to Abode."
|
||||
"invalid_auth": "[%key:common::config_flow::error::invalid_auth%]",
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
|
||||
},
|
||||
"abort": {
|
||||
"single_instance_allowed": "Only a single configuration of Abode is allowed."
|
||||
"single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,13 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Nom\u00e9s es permet una \u00fanica configuraci\u00f3 d'Abode."
|
||||
"single_instance_allowed": "Ja configurat. Nom\u00e9s \u00e9s possible una sola configuraci\u00f3."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Ha fallat la connexi\u00f3",
|
||||
"connection_error": "No es pot connectar amb Abode.",
|
||||
"identifier_exists": "Compte ja registrat.",
|
||||
"invalid_auth": "Autenticaci\u00f3 inv\u00e0lida",
|
||||
"invalid_credentials": "Credencials inv\u00e0lides."
|
||||
},
|
||||
"step": {
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Je povolena pouze jedna konfigurace Abode."
|
||||
"single_instance_allowed": "Ji\u017e nastaveno. Je mo\u017en\u00e1 pouze jedin\u00e1 konfigurace."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Nepoda\u0159ilo se p\u0159ipojit",
|
||||
"connection_error": "Nelze se p\u0159ipojit k Abode.",
|
||||
"identifier_exists": "\u00da\u010det je ji\u017e zaregistrov\u00e1n.",
|
||||
"invalid_auth": "Neplatn\u00e9 ov\u011b\u0159en\u00ed",
|
||||
"invalid_credentials": "Neplatn\u00e9 p\u0159ihla\u0161ovac\u00ed \u00fadaje."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Heslo",
|
||||
"username": "E-mailov\u00e1 adresa"
|
||||
"username": "E-mail"
|
||||
},
|
||||
"title": "Vypl\u0148te p\u0159ihla\u0161ovac\u00ed \u00fadaje Abode"
|
||||
}
|
||||
|
|
8
homeassistant/components/abode/translations/el.json
Normal file
8
homeassistant/components/abode/translations/el.json
Normal file
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"config": {
|
||||
"error": {
|
||||
"cannot_connect": "\u0391\u03c0\u03bf\u03c4\u03c5\u03c7\u03af\u03b1 \u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7\u03c2",
|
||||
"invalid_auth": "\u039c\u03b7 \u03ad\u03b3\u03ba\u03c5\u03c1\u03b7 \u03b1\u03c5\u03b8\u03b5\u03bd\u03c4\u03b9\u03ba\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b7"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,11 +1,13 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Only a single configuration of Abode is allowed."
|
||||
"single_instance_allowed": "Already configured. Only a single configuration possible."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Failed to connect",
|
||||
"connection_error": "Unable to connect to Abode.",
|
||||
"identifier_exists": "Account already registered.",
|
||||
"invalid_auth": "Invalid authentication",
|
||||
"invalid_credentials": "Invalid credentials."
|
||||
},
|
||||
"step": {
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Solo se permite una \u00fanica configuraci\u00f3n de Abode."
|
||||
"single_instance_allowed": "Ya est\u00e1 configurado. Solo es posible una \u00fanica configuraci\u00f3n."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "No se pudo conectar",
|
||||
"connection_error": "No se puede conectar a Abode.",
|
||||
"identifier_exists": "Cuenta ya registrada.",
|
||||
"invalid_auth": "Autenticaci\u00f3n no v\u00e1lida",
|
||||
"invalid_credentials": "Credenciales inv\u00e1lidas."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Contrase\u00f1a",
|
||||
"username": "Direcci\u00f3n de correo electr\u00f3nico"
|
||||
"username": "Correo electr\u00f3nico"
|
||||
},
|
||||
"title": "Rellene la informaci\u00f3n de acceso Abode"
|
||||
}
|
||||
|
|
23
homeassistant/components/abode/translations/et.json
Normal file
23
homeassistant/components/abode/translations/et.json
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Juba seadistatud. V\u00f5imalik on ainult \u00fcks seadistamine."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "\u00dchendamine nurjus",
|
||||
"connection_error": "\u00dchendus Abode-iga nurjus.",
|
||||
"identifier_exists": "Konto on juba seadistatud",
|
||||
"invalid_auth": "Tuvastamise viga",
|
||||
"invalid_credentials": "Sobimatu mandaat."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Salas\u00f5na",
|
||||
"username": "E-post"
|
||||
},
|
||||
"title": "Sisesta oma Abode sisselogimisteave"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,8 +4,10 @@
|
|||
"single_instance_allowed": "Une seule configuration d'Abode est autoris\u00e9e."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "\u00c9chec de connexion",
|
||||
"connection_error": "Impossible de se connecter \u00e0 Abode.",
|
||||
"identifier_exists": "Compte d\u00e9j\u00e0 enregistr\u00e9.",
|
||||
"invalid_auth": "Authentification invalide",
|
||||
"invalid_credentials": "Informations d'identification invalides."
|
||||
},
|
||||
"step": {
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "\u00c8 consentita una sola configurazione di Abode."
|
||||
"single_instance_allowed": "Gi\u00e0 configurato. \u00c8 possibile una sola configurazione."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Impossibile connettersi",
|
||||
"connection_error": "Impossibile connettersi ad Abode.",
|
||||
"identifier_exists": "Account gi\u00e0 registrato",
|
||||
"invalid_auth": "Autenticazione non valida",
|
||||
"invalid_credentials": "Credenziali non valide"
|
||||
},
|
||||
"step": {
|
||||
|
|
|
@ -4,8 +4,10 @@
|
|||
"single_instance_allowed": "N\u00ebmmen eng eenzeg Konfiguratioun vun ZHA ass erlaabt."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Feeler beim verbannen",
|
||||
"connection_error": "Kann sech net mat Abode verbannen.",
|
||||
"identifier_exists": "Konto ass scho registr\u00e9iert",
|
||||
"invalid_auth": "Ong\u00eblteg Authentifikatioun",
|
||||
"invalid_credentials": "Ong\u00eblteg Login Informatioune"
|
||||
},
|
||||
"step": {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
"single_instance_allowed": "Slechts een enkele configuratie van Abode is toegestaan."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Kan geen verbinding maken",
|
||||
"connection_error": "Kan geen verbinding maken met Abode.",
|
||||
"identifier_exists": "Account is al geregistreerd.",
|
||||
"invalid_credentials": "Ongeldige inloggegevens."
|
||||
|
|
|
@ -1,18 +1,20 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Bare en enkelt konfigurasjon av Abode er tillatt."
|
||||
"single_instance_allowed": "Allerede konfigurert. Bare \u00e9n enkelt konfigurasjon er mulig."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Tilkobling mislyktes",
|
||||
"connection_error": "Kan ikke koble til Abode.",
|
||||
"identifier_exists": "Kontoen er allerede registrert.",
|
||||
"invalid_auth": "Ugyldig godkjenning",
|
||||
"invalid_credentials": "Ugyldig legitimasjon"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"password": "Passord",
|
||||
"username": "E-postadresse"
|
||||
"username": "E-post"
|
||||
},
|
||||
"title": "Fyll ut innloggingsinformasjonen for Abode"
|
||||
}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Dozwolona jest tylko jedna konfiguracja Abode."
|
||||
"single_instance_allowed": "Ju\u017c skonfigurowano. Mo\u017cliwa jest tylko jedna konfiguracja."
|
||||
},
|
||||
"error": {
|
||||
"connection_error": "Nie mo\u017cna po\u0142\u0105czy\u0107 si\u0119 z Abode.",
|
||||
"identifier_exists": "Konto jest ju\u017c zarejestrowane.",
|
||||
"cannot_connect": "Nie mo\u017cna nawi\u0105za\u0107 po\u0142\u0105czenia",
|
||||
"connection_error": "Nie mo\u017cna po\u0142\u0105czy\u0107 si\u0119 z Abode",
|
||||
"identifier_exists": "Konto jest ju\u017c zarejestrowane",
|
||||
"invalid_auth": "Niepoprawne uwierzytelnienie",
|
||||
"invalid_credentials": "Nieprawid\u0142owe dane uwierzytelniaj\u0105ce"
|
||||
},
|
||||
"step": {
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0443\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430."
|
||||
"single_instance_allowed": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0443\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u0443 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f.",
|
||||
"connection_error": "\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f \u043a Abode.",
|
||||
"identifier_exists": "\u0423\u0447\u0451\u0442\u043d\u0430\u044f \u0437\u0430\u043f\u0438\u0441\u044c \u0443\u0436\u0435 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0430.",
|
||||
"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_credentials": "\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0435 \u0443\u0447\u0451\u0442\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435."
|
||||
},
|
||||
"step": {
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "\u50c5\u5141\u8a31\u8a2d\u5b9a\u4e00\u7d44 Abode\u3002"
|
||||
"single_instance_allowed": "\u50c5\u80fd\u8a2d\u5b9a\u4e00\u7d44\u8a2d\u5099\u3002"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "\u9023\u7dda\u5931\u6557",
|
||||
"connection_error": "\u7121\u6cd5\u9023\u7dda\u81f3 Abode\u3002",
|
||||
"identifier_exists": "\u5e33\u865f\u5df2\u8a3b\u518a\u3002",
|
||||
"invalid_auth": "\u9a57\u8b49\u78bc\u7121\u6548",
|
||||
"invalid_credentials": "\u6191\u8b49\u7121\u6548\u3002"
|
||||
},
|
||||
"step": {
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
"title": "AccuWeather",
|
||||
"description": "If you need help with the configuration have a look here: https://www.home-assistant.io/integrations/accuweather/\n\nSome sensors are not enabled by default. You can enable them in the entity registry after the integration configuration.\nWeather forecast is not enabled by default. You can enable it in the integration options.",
|
||||
"data": {
|
||||
"name": "Name of the integration",
|
||||
"name": "[%key:common::config_flow::data::name%]",
|
||||
"api_key": "[%key:common::config_flow::data::api_key%]",
|
||||
"latitude": "Latitude",
|
||||
"longitude": "Longitude"
|
||||
"latitude": "[%key:common::config_flow::data::latitude%]",
|
||||
"longitude": "[%key:common::config_flow::data::longitude%]"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
"api_key": "Clau API",
|
||||
"latitude": "Latitud",
|
||||
"longitude": "Longitud",
|
||||
"name": "Nom de la integraci\u00f3"
|
||||
"name": "Nom"
|
||||
},
|
||||
"description": "Si necessites ajuda amb la configuraci\u00f3, consulta els seg\u00fcent enlla\u00e7: https://www.home-assistant.io/integrations/accuweather/ \n\n Alguns sensors no estan activats de manera predeterminada. Els pots activar des del registre d'entitats, despr\u00e9s de la configurraci\u00f3 de la integraci\u00f3.\n La previsi\u00f3 meteorol\u00f2gica no est\u00e0 activada de manera predeterminada. Pots activar-la en les opcions de la integraci\u00f3.",
|
||||
"title": "AccuWeather"
|
||||
|
|
|
@ -1,11 +1,34 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Ji\u017e nastaveno. Je mo\u017en\u00e1 pouze jedin\u00e1 konfigurace."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Nepoda\u0159ilo se p\u0159ipojit",
|
||||
"invalid_api_key": "Neplatn\u00fd kl\u00ed\u010d API",
|
||||
"requests_exceeded": "Byl p\u0159ekro\u010den povolen\u00fd po\u010det po\u017eadavk\u016f pro API Accuweather. Mus\u00edte po\u010dkat nebo zm\u011bnit API kl\u00ed\u010d."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"api_key": "Kl\u00ed\u010d API",
|
||||
"latitude": "Zem\u011bpisn\u00e1 \u0161\u00ed\u0159ka",
|
||||
"longitude": "Zem\u011bpisn\u00e1 d\u00e9lka"
|
||||
}
|
||||
"longitude": "Zem\u011bpisn\u00e1 d\u00e9lka",
|
||||
"name": "Jm\u00e9no"
|
||||
},
|
||||
"description": "Pokud pot\u0159ebujete pomoc s nastaven\u00ed, pod\u00edvejte se na: https://www.home-assistant.io/integrations/accuweather/\n\nN\u011bkter\u00e9 senzory nejsou ve v\u00fdchoz\u00edm nastaven\u00ed povoleny. M\u016f\u017eete je povolit po nastaven\u00ed integrace v registru entit.\nP\u0159edpov\u011b\u010f po\u010das\u00ed nen\u00ed ve v\u00fdchoz\u00edm nastaven\u00ed povolena. M\u016f\u017eete ji povolit v mo\u017enostech integrace.",
|
||||
"title": "AccuWeather"
|
||||
}
|
||||
}
|
||||
},
|
||||
"options": {
|
||||
"step": {
|
||||
"user": {
|
||||
"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.",
|
||||
"title": "Mo\u017enosti AccuWeather"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
"api_key": "API Key",
|
||||
"latitude": "Latitude",
|
||||
"longitude": "Longitude",
|
||||
"name": "Name of the integration"
|
||||
"name": "Name"
|
||||
},
|
||||
"description": "If you need help with the configuration have a look here: https://www.home-assistant.io/integrations/accuweather/\n\nSome sensors are not enabled by default. You can enable them in the entity registry after the integration configuration.\nWeather forecast is not enabled by default. You can enable it in the integration options.",
|
||||
"title": "AccuWeather"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Ya est\u00e1 configurado. S\u00f3lo es posible una \u00fanica configuraci\u00f3n."
|
||||
"single_instance_allowed": "Ya est\u00e1 configurado. Solo es posible una \u00fanica configuraci\u00f3n."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "No se pudo conectar",
|
||||
|
@ -14,7 +14,7 @@
|
|||
"api_key": "Clave API",
|
||||
"latitude": "Latitud",
|
||||
"longitude": "Longitud",
|
||||
"name": "Nombre de la integraci\u00f3n"
|
||||
"name": "Nombre"
|
||||
},
|
||||
"description": "Si necesitas ayuda con la configuraci\u00f3n, echa un vistazo aqu\u00ed: https://www.home-assistant.io/integrations/accuweather/ \n\nEl pron\u00f3stico del tiempo no est\u00e1 habilitado por defecto. Puedes habilitarlo en las opciones de la integraci\u00f3n.",
|
||||
"title": "AccuWeather"
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"single_instance_allowed": "Sidumine juba tehtud. V\u00f5imalik on ainult 1 sidumine,"
|
||||
"single_instance_allowed": "Sidumine juba tehtud. V\u00f5imalik on ainult 1 sidumine."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "\u00dchendus eba\u00f5nnestus",
|
||||
"cannot_connect": "\u00dchendamine nurjus",
|
||||
"invalid_api_key": "API v\u00f5ti on vale",
|
||||
"requests_exceeded": "Accuweatheri API-le esitatud p\u00e4ringute piirarv on \u00fcletatud. Peate ootama (v\u00f5i muutma API v\u00f5tit)."
|
||||
},
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
"api_key": "Chiave API",
|
||||
"latitude": "Latitudine",
|
||||
"longitude": "Logitudine",
|
||||
"name": "Nome dell'integrazione"
|
||||
"name": "Nome"
|
||||
},
|
||||
"description": "Se hai bisogno di aiuto con la configurazione dai un'occhiata qui: https://www.home-assistant.io/integrations/accuweather/ \n\nAlcuni sensori non sono abilitati per impostazione predefinita. \u00c8 possibile abilitarli nel registro entit\u00e0 dopo la configurazione di integrazione. \nLe previsioni meteo non sono abilitate per impostazione predefinita. Puoi abilitarle nelle opzioni di integrazione.",
|
||||
"title": "AccuWeather"
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
"api_key": "API Schl\u00ebssel",
|
||||
"latitude": "Breedegrad",
|
||||
"longitude": "L\u00e4ngegrad",
|
||||
"name": "Numm vun der Integratioun"
|
||||
"name": "Numm"
|
||||
},
|
||||
"description": "Falls du H\u00ebllef mat der Konfiguratioun brauch kuck h\u00e9i:\nhttps://www.home-assistant.io/integrations/accuweather/\n\nWieder Pr\u00e9visounen si standardm\u00e9isseg net aktiv. Du kanns d\u00e9i an den Optioune vun der Integratioun aschalten.",
|
||||
"title": "AccuWeather"
|
||||
|
|
12
homeassistant/components/accuweather/translations/nl.json
Normal file
12
homeassistant/components/accuweather/translations/nl.json
Normal file
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"config": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"longitude": "Lengtegraad",
|
||||
"name": "Naam"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,7 +4,7 @@
|
|||
"single_instance_allowed": "Allerede konfigurert. Bare \u00e9n enkelt konfigurasjon er mulig."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Tilkobling mislyktes.",
|
||||
"cannot_connect": "Tilkobling mislyktes",
|
||||
"invalid_api_key": "Ugyldig API-n\u00f8kkel",
|
||||
"requests_exceeded": "Det tillatte antallet foresp\u00f8rsler til Accuweather API er overskredet. Du m\u00e5 vente eller endre API-n\u00f8kkel."
|
||||
},
|
||||
|
@ -14,7 +14,7 @@
|
|||
"api_key": "API-n\u00f8kkel",
|
||||
"latitude": "Breddegrad",
|
||||
"longitude": "Lengdegrad",
|
||||
"name": "Navn p\u00e5 integrasjon"
|
||||
"name": "Navn"
|
||||
},
|
||||
"description": "Hvis du trenger hjelp med konfigurasjonen, kan du se her: https://www.home-assistant.io/integrations/accuweather/ \n\n Noen sensorer er ikke aktivert som standard. Du kan aktivere dem i enhetsregisteret etter integrasjonskonfigurasjonen. \n V\u00e6rmelding er ikke aktivert som standard. Du kan aktivere det i integrasjonsalternativene.",
|
||||
"title": ""
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
},
|
||||
"error": {
|
||||
"cannot_connect": "Nie mo\u017cna nawi\u0105za\u0107 po\u0142\u0105czenia",
|
||||
"invalid_api_key": "Nieprawid\u0142owy klucz API.",
|
||||
"invalid_api_key": "Nieprawid\u0142owy klucz API",
|
||||
"requests_exceeded": "Dozwolona liczba zapyta\u0144 do interfejsu API AccuWeather zosta\u0142a przekroczona. Musisz poczeka\u0107 lub zmieni\u0107 klucz API."
|
||||
},
|
||||
"step": {
|
||||
|
@ -14,7 +14,7 @@
|
|||
"api_key": "Klucz API",
|
||||
"latitude": "Szeroko\u015b\u0107 geograficzna",
|
||||
"longitude": "D\u0142ugo\u015b\u0107 geograficzna",
|
||||
"name": "Nazwa integracji"
|
||||
"name": "Nazwa"
|
||||
},
|
||||
"description": "Je\u015bli potrzebujesz pomocy z konfiguracj\u0105, przejd\u017a na stron\u0119: https://www.home-assistant.io/integrations/accuweather/ \n\nCz\u0119\u015b\u0107 sensor\u00f3w nie jest w\u0142\u0105czona domy\u015blnie. Mo\u017cesz je w\u0142\u0105czy\u0107 w rejestrze encji po konfiguracji integracji.\nPrognoza pogody nie jest domy\u015blnie w\u0142\u0105czona. Mo\u017cesz j\u0105 w\u0142\u0105czy\u0107 w opcjach integracji.",
|
||||
"title": "AccuWeather"
|
||||
|
@ -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 minut zamiast co 32 minut.",
|
||||
"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.",
|
||||
"title": "Opcje AccuWeather"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"state": {
|
||||
"accuweather__pressure_tendency": {
|
||||
"falling": "Fallande",
|
||||
"rising": "Stigande"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -14,7 +14,7 @@
|
|||
"api_key": "API \u5bc6\u9470",
|
||||
"latitude": "\u7def\u5ea6",
|
||||
"longitude": "\u7d93\u5ea6",
|
||||
"name": "\u6574\u5408\u540d\u7a31"
|
||||
"name": "\u540d\u7a31"
|
||||
},
|
||||
"description": "\u5047\u5982\u4f60\u9700\u8981\u5354\u52a9\u9032\u884c\u8a2d\u5b9a\uff0c\u8acb\u53c3\u95b1\uff1ahttps://www.home-assistant.io/integrations/accuweather/\n\n\u67d0\u4e9b\u50b3\u611f\u5668\u9810\u8a2d\u70ba\u672a\u555f\u7528\uff0c\u53ef\u4ee5\u65bc\u6574\u5408\u8a2d\u5b9a\u4e2d\u555f\u7528\u9019\u4e9b\u5be6\u9ad4\u3002\u5929\u6c23\u9810\u5831\u9810\u8a2d\u672a\u958b\u555f\u3002\u53ef\u4ee5\u65bc\u6574\u5408\u9078\u9805\u4e2d\u958b\u555f\u3002",
|
||||
"title": "AccuWeather"
|
||||
|
|
|
@ -45,7 +45,7 @@ class AcmedaFlowHandler(config_entries.ConfigFlow, domain=DOMAIN):
|
|||
pass
|
||||
|
||||
if len(hubs) == 0:
|
||||
return self.async_abort(reason="all_configured")
|
||||
return self.async_abort(reason="no_devices_found")
|
||||
|
||||
if len(hubs) == 1:
|
||||
return await self.async_create(hubs[0])
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
}
|
||||
},
|
||||
"abort": {
|
||||
"all_configured": "No new Pulse hubs discovered."
|
||||
"no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"all_configured": "No s'han descobert nous hubs de Pulse."
|
||||
"all_configured": "No s'han descobert nous hubs de Pulse.",
|
||||
"no_devices_found": "No s'han trobat dispositius a la xarxa"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
|
|
7
homeassistant/components/acmeda/translations/cs.json
Normal file
7
homeassistant/components/acmeda/translations/cs.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"no_devices_found": "V s\u00edti nebyla nalezena \u017e\u00e1dn\u00e1 za\u0159\u00edzen\u00ed"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"all_configured": "No new Pulse hubs discovered."
|
||||
"all_configured": "No new Pulse hubs discovered.",
|
||||
"no_devices_found": "No devices found on the network"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"all_configured": "No se han descubierto nuevos hubs Pulse."
|
||||
"all_configured": "No se han descubierto nuevos hubs Pulse.",
|
||||
"no_devices_found": "No se encontraron dispositivos en la red"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
|
|
17
homeassistant/components/acmeda/translations/et.json
Normal file
17
homeassistant/components/acmeda/translations/et.json
Normal file
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"all_configured": "Uusi Pulse'i jaotureid ei avastatud.",
|
||||
"no_devices_found": "V\u00f5rgus ei tuvastatud \u00fchtegi seadet"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"id": "Hosti ID"
|
||||
},
|
||||
"title": "Vali lisatav jaotur"
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": ""
|
||||
}
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"all_configured": "Aucun nouveau hub Pulse n'a \u00e9t\u00e9 d\u00e9couvert."
|
||||
"all_configured": "Aucun nouveau hub Pulse n'a \u00e9t\u00e9 d\u00e9couvert.",
|
||||
"no_devices_found": "Aucun appareil trouv\u00e9 sur le r\u00e9seau"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"all_configured": "Non sono stati scoperti nuovi hub Pulse."
|
||||
"all_configured": "Non sono stati scoperti nuovi hub Pulse.",
|
||||
"no_devices_found": "Nessun dispositivo trovato sulla rete"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"all_configured": "Ingen nye Pulse-hub oppdaget."
|
||||
"all_configured": "Ingen nye Pulse-hub oppdaget.",
|
||||
"no_devices_found": "Ingen enheter funnet p\u00e5 nettverket"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"all_configured": "Nie wykryto hub\u00f3w Pulse."
|
||||
"all_configured": "Nie wykryto hub\u00f3w Pulse",
|
||||
"no_devices_found": "Nie znaleziono urz\u0105dze\u0144 w sieci"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"all_configured": "\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u043d\u0435 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u044b."
|
||||
"all_configured": "\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u043d\u0435 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u044b.",
|
||||
"no_devices_found": "\u0423\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u044b \u0432 \u0441\u0435\u0442\u0438."
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"all_configured": "\u672a\u641c\u5c0b\u5230 Pulse hub"
|
||||
"all_configured": "\u672a\u641c\u5c0b\u5230 Pulse hub",
|
||||
"no_devices_found": "\u7db2\u8def\u4e0a\u627e\u4e0d\u5230\u8a2d\u5099"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
"""Config flow to configure the AdGuard Home integration."""
|
||||
import logging
|
||||
|
||||
from adguardhome import AdGuardHome, AdGuardHomeConnectionError
|
||||
import voluptuous as vol
|
||||
|
||||
|
@ -17,8 +15,6 @@ from homeassistant.const import (
|
|||
)
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@config_entries.HANDLERS.register(DOMAIN)
|
||||
class AdGuardHomeFlowHandler(ConfigFlow):
|
||||
|
@ -80,7 +76,7 @@ class AdGuardHomeFlowHandler(ConfigFlow):
|
|||
try:
|
||||
await adguard.version()
|
||||
except AdGuardHomeConnectionError:
|
||||
errors["base"] = "connection_error"
|
||||
errors["base"] = "cannot_connect"
|
||||
return await self._show_setup_form(errors)
|
||||
|
||||
return self.async_create_entry(
|
||||
|
@ -152,7 +148,7 @@ class AdGuardHomeFlowHandler(ConfigFlow):
|
|||
try:
|
||||
await adguard.version()
|
||||
except AdGuardHomeConnectionError:
|
||||
errors["base"] = "connection_error"
|
||||
errors["base"] = "cannot_connect"
|
||||
return await self._show_hassio_form(errors)
|
||||
|
||||
return self.async_create_entry(
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
"""Support for AdGuard Home sensors."""
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
|
||||
from adguardhome import AdGuardHomeConnectionError
|
||||
|
||||
|
@ -15,8 +14,6 @@ from homeassistant.const import PERCENTAGE, TIME_MILLISECONDS
|
|||
from homeassistant.exceptions import PlatformNotReady
|
||||
from homeassistant.helpers.typing import HomeAssistantType
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
SCAN_INTERVAL = timedelta(seconds=300)
|
||||
PARALLEL_UPDATES = 4
|
||||
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
"password": "[%key:common::config_flow::data::password%]",
|
||||
"port": "[%key:common::config_flow::data::port%]",
|
||||
"username": "[%key:common::config_flow::data::username%]",
|
||||
"ssl": "AdGuard Home uses a SSL certificate",
|
||||
"verify_ssl": "AdGuard Home uses a proper certificate"
|
||||
"ssl": "[%key:common::config_flow::data::ssl%]",
|
||||
"verify_ssl": "[%key:common::config_flow::data::verify_ssl%]"
|
||||
}
|
||||
},
|
||||
"hassio_confirm": {
|
||||
|
@ -17,10 +17,12 @@
|
|||
"description": "Do you want to configure Home Assistant to connect to the AdGuard Home provided by the Hass.io add-on: {addon}?"
|
||||
}
|
||||
},
|
||||
"error": { "connection_error": "Failed to connect." },
|
||||
"error": {
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
|
||||
},
|
||||
"abort": {
|
||||
"existing_instance_updated": "Updated existing configuration.",
|
||||
"single_instance_allowed": "Only a single configuration of AdGuard Home is allowed."
|
||||
"single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
"config": {
|
||||
"abort": {
|
||||
"existing_instance_updated": "S'ha actualitzat la configuraci\u00f3 existent.",
|
||||
"single_instance_allowed": "Nom\u00e9s es permet una \u00fanica configuraci\u00f3 d'AdGuard Home."
|
||||
"single_instance_allowed": "Ja configurat. Nom\u00e9s \u00e9s possible una sola configuraci\u00f3."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Ha fallat la connexi\u00f3",
|
||||
"connection_error": "No s'ha pogut connectar."
|
||||
},
|
||||
"step": {
|
||||
|
@ -17,9 +18,9 @@
|
|||
"host": "[%key::common::config_flow::data::host%]",
|
||||
"password": "[%key::common::config_flow::data::password%]",
|
||||
"port": "[%key::common::config_flow::data::port%]",
|
||||
"ssl": "AdGuard Home utilitza un certificat SSL",
|
||||
"ssl": "Utilitza un certificat SSL",
|
||||
"username": "[%key::common::config_flow::data::username%]",
|
||||
"verify_ssl": "AdGuard Home utilitza un certificat adequat"
|
||||
"verify_ssl": "Verifica el certificat SSL"
|
||||
},
|
||||
"description": "Configuraci\u00f3 de la inst\u00e0ncia d'AdGuard Home, permet el control i la monitoritzaci\u00f3."
|
||||
}
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"existing_instance_updated": "St\u00e1vaj\u00edc\u00ed nastaven\u00ed aktualizov\u00e1no.",
|
||||
"single_instance_allowed": "Ji\u017e nastaveno. Je mo\u017en\u00e1 pouze jedin\u00e1 konfigurace."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Nepoda\u0159ilo se p\u0159ipojit",
|
||||
"connection_error": "Nepoda\u0159ilo se p\u0159ipojit."
|
||||
},
|
||||
"step": {
|
||||
"hassio_confirm": {
|
||||
"description": "Chcete nakonfigurovat slu\u017ebu Home Assistant pro p\u0159ipojen\u00ed k AddGuard pomoc\u00ed hass.io {addon}?",
|
||||
|
@ -10,7 +18,9 @@
|
|||
"host": "Hostitel",
|
||||
"password": "Heslo",
|
||||
"port": "Port",
|
||||
"username": "U\u017eivatelsk\u00e9 jm\u00e9no"
|
||||
"ssl": "Pou\u017e\u00edv\u00e1 SSL certifik\u00e1t",
|
||||
"username": "U\u017eivatelsk\u00e9 jm\u00e9no",
|
||||
"verify_ssl": "Ov\u011b\u0159it certifik\u00e1t SSL"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
7
homeassistant/components/adguard/translations/el.json
Normal file
7
homeassistant/components/adguard/translations/el.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"config": {
|
||||
"error": {
|
||||
"cannot_connect": "\u0391\u03c0\u03bf\u03c4\u03c5\u03c7\u03af\u03b1 \u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7\u03c2"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,9 +2,10 @@
|
|||
"config": {
|
||||
"abort": {
|
||||
"existing_instance_updated": "Updated existing configuration.",
|
||||
"single_instance_allowed": "Only a single configuration of AdGuard Home is allowed."
|
||||
"single_instance_allowed": "Already configured. Only a single configuration possible."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Failed to connect",
|
||||
"connection_error": "Failed to connect."
|
||||
},
|
||||
"step": {
|
||||
|
@ -17,9 +18,9 @@
|
|||
"host": "Host",
|
||||
"password": "Password",
|
||||
"port": "Port",
|
||||
"ssl": "AdGuard Home uses a SSL certificate",
|
||||
"ssl": "Uses an SSL certificate",
|
||||
"username": "Username",
|
||||
"verify_ssl": "AdGuard Home uses a proper certificate"
|
||||
"verify_ssl": "Verify SSL certificate"
|
||||
},
|
||||
"description": "Set up your AdGuard Home instance to allow monitoring and control."
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
"single_instance_allowed": "S\u00f3lo se permite una \u00fanica configuraci\u00f3n de AdGuard Home."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "No se pudo conectar",
|
||||
"connection_error": "No se conect\u00f3."
|
||||
},
|
||||
"step": {
|
||||
|
|
29
homeassistant/components/adguard/translations/et.json
Normal file
29
homeassistant/components/adguard/translations/et.json
Normal file
|
@ -0,0 +1,29 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"existing_instance_updated": "Olemasolevad seaded v\u00e4rskendatud.",
|
||||
"single_instance_allowed": "Juba seadistatud. V\u00f5imalik on ainult \u00fcks seadistamine."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "\u00dchendamine nurjus",
|
||||
"connection_error": "\u00dchenduse loomine nurjus"
|
||||
},
|
||||
"step": {
|
||||
"hassio_confirm": {
|
||||
"description": "Kas soovid seadistada Home Assistant-i \u00fchenduse AdGuard Home'iga mida pakub Hass.io lisandmoodul: {addon} ?",
|
||||
"title": "AdGuard Home Hass.io pistikprogrammi kaudu"
|
||||
},
|
||||
"user": {
|
||||
"data": {
|
||||
"host": "",
|
||||
"password": "Salas\u00f5na",
|
||||
"port": "",
|
||||
"ssl": "Kasuta SSL sertifikaati",
|
||||
"username": "Kasutajanimi",
|
||||
"verify_ssl": "Kontrolli SSL sertifikaati"
|
||||
},
|
||||
"description": "Seadista AdGuard Home'i sidumine, et v\u00f5imaldada j\u00e4lgimist ja juhtimist."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
"single_instance_allowed": "Une seule configuration d'AdGuard Home est autoris\u00e9e."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "\u00c9chec de connexion",
|
||||
"connection_error": "\u00c9chec de connexion."
|
||||
},
|
||||
"step": {
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
"config": {
|
||||
"abort": {
|
||||
"existing_instance_updated": "Configurazione esistente aggiornata.",
|
||||
"single_instance_allowed": "\u00c8 consentita solo una singola configurazione di AdGuard Home."
|
||||
"single_instance_allowed": "Gi\u00e0 configurato. \u00c8 possibile una sola configurazione."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Impossibile connettersi",
|
||||
"connection_error": "Impossibile connettersi."
|
||||
},
|
||||
"step": {
|
||||
|
@ -17,9 +18,9 @@
|
|||
"host": "Host",
|
||||
"password": "Password",
|
||||
"port": "Porta",
|
||||
"ssl": "AdGuard Home utilizza un certificato SSL",
|
||||
"ssl": "Utilizza un certificato SSL",
|
||||
"username": "Nome utente",
|
||||
"verify_ssl": "AdGuard Home utilizza un certificato appropriato"
|
||||
"verify_ssl": "Verificare il certificato SSL"
|
||||
},
|
||||
"description": "Configura l'istanza di AdGuard Home per consentire il monitoraggio e il controllo."
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
"single_instance_allowed": "N\u00ebmmen eng eenzeg Konfiguratioun vun AdGuard Home ass erlaabt."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Feeler beim verbannen",
|
||||
"connection_error": "Feeler beim verbannen."
|
||||
},
|
||||
"step": {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
"single_instance_allowed": "Slechts \u00e9\u00e9n configuratie van AdGuard Home is toegestaan."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Kan geen verbinding maken",
|
||||
"connection_error": "Kon niet verbinden."
|
||||
},
|
||||
"step": {
|
||||
|
@ -15,6 +16,7 @@
|
|||
"user": {
|
||||
"data": {
|
||||
"password": "Wachtwoord",
|
||||
"port": "Poort",
|
||||
"ssl": "AdGuard Home maakt gebruik van een SSL certificaat",
|
||||
"username": "Gebruikersnaam",
|
||||
"verify_ssl": "AdGuard Home maakt gebruik van een goed certificaat"
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
"config": {
|
||||
"abort": {
|
||||
"existing_instance_updated": "Oppdatert eksisterende konfigurasjon.",
|
||||
"single_instance_allowed": "Kun en konfigurasjon av AdGuard Hjemer tillatt."
|
||||
"single_instance_allowed": "Allerede konfigurert. Bare \u00e9n enkelt konfigurasjon er mulig."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Tilkobling mislyktes",
|
||||
"connection_error": "Tilkobling mislyktes."
|
||||
},
|
||||
"step": {
|
||||
|
@ -16,10 +17,10 @@
|
|||
"data": {
|
||||
"host": "Vert",
|
||||
"password": "Passord",
|
||||
"port": "",
|
||||
"ssl": "AdGuard Hjem bruker et SSL-sertifikat",
|
||||
"port": "Port",
|
||||
"ssl": "Bruker et SSL-sertifikat",
|
||||
"username": "Brukernavn",
|
||||
"verify_ssl": "AdGuard Home bruker et riktig sertifikat"
|
||||
"verify_ssl": "Verifisere SSL-sertifikat"
|
||||
},
|
||||
"description": "Sett opp din AdGuard Hjem instans for \u00e5 tillate overv\u00e5king og kontroll."
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"existing_instance_updated": "Zaktualizowano istniej\u0105c\u0105 konfiguracj\u0119.",
|
||||
"single_instance_allowed": "Dozwolona jest tylko jedna konfiguracja AdGuard Home."
|
||||
"existing_instance_updated": "Zaktualizowano istniej\u0105c\u0105 konfiguracj\u0119",
|
||||
"single_instance_allowed": "Ju\u017c skonfigurowano. Mo\u017cliwa jest tylko jedna konfiguracja."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Nie mo\u017cna nawi\u0105za\u0107 po\u0142\u0105czenia",
|
||||
"connection_error": "Nie mo\u017cna nawi\u0105za\u0107 po\u0142\u0105czenia"
|
||||
},
|
||||
"step": {
|
||||
|
@ -17,9 +18,9 @@
|
|||
"host": "Nazwa hosta lub adres IP",
|
||||
"password": "Has\u0142o",
|
||||
"port": "Port",
|
||||
"ssl": "AdGuard Home u\u017cywa certyfikatu SSL",
|
||||
"ssl": "Certyfikat SSL",
|
||||
"username": "Nazwa u\u017cytkownika",
|
||||
"verify_ssl": "AdGuard Home u\u017cywa odpowiedniego certyfikatu."
|
||||
"verify_ssl": "Weryfikacja certyfikatu SSL"
|
||||
},
|
||||
"description": "Skonfiguruj instancj\u0119 AdGuard Home, aby umo\u017cliwi\u0107 monitorowanie i kontrol\u0119."
|
||||
}
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
"config": {
|
||||
"abort": {
|
||||
"existing_instance_updated": "\u041a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0430.",
|
||||
"single_instance_allowed": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0443\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430."
|
||||
"single_instance_allowed": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0443\u0436\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0430. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u0443 \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u044e."
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f.",
|
||||
"connection_error": "\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f."
|
||||
},
|
||||
"step": {
|
||||
|
@ -17,9 +18,9 @@
|
|||
"host": "\u0425\u043e\u0441\u0442",
|
||||
"password": "\u041f\u0430\u0440\u043e\u043b\u044c",
|
||||
"port": "\u041f\u043e\u0440\u0442",
|
||||
"ssl": "AdGuard Home \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442 SSL",
|
||||
"ssl": "\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442 SSL",
|
||||
"username": "\u041b\u043e\u0433\u0438\u043d",
|
||||
"verify_ssl": "AdGuard Home \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0439 \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442"
|
||||
"verify_ssl": "\u041f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0441\u0435\u0440\u0442\u0438\u0444\u0438\u043a\u0430\u0442 SSL"
|
||||
},
|
||||
"description": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u0442\u0435 Home Assistant \u0434\u043b\u044f \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0438 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f AdGuard Home."
|
||||
}
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
"abort": {
|
||||
"existing_instance_updated": "\u66f4\u65b0\u4e86\u73b0\u6709\u914d\u7f6e\u3002"
|
||||
},
|
||||
"error": {
|
||||
"connection_error": "\u8fde\u63a5\u5931\u8d25\u3002"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
|
|
|
@ -2,9 +2,10 @@
|
|||
"config": {
|
||||
"abort": {
|
||||
"existing_instance_updated": "\u5df2\u66f4\u65b0\u73fe\u6709\u8a2d\u5b9a\u3002",
|
||||
"single_instance_allowed": "\u50c5\u5141\u8a31\u8a2d\u5b9a\u4e00\u7d44 AdGuard Home\u3002"
|
||||
"single_instance_allowed": "\u50c5\u80fd\u8a2d\u5b9a\u4e00\u7d44\u8a2d\u5099\u3002"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "\u9023\u7dda\u5931\u6557",
|
||||
"connection_error": "\u9023\u7dda\u5931\u6557\u3002"
|
||||
},
|
||||
"step": {
|
||||
|
@ -17,9 +18,9 @@
|
|||
"host": "\u4e3b\u6a5f\u7aef",
|
||||
"password": "\u5bc6\u78bc",
|
||||
"port": "\u901a\u8a0a\u57e0",
|
||||
"ssl": "AdGuard Home \u4f7f\u7528 SSL \u8a8d\u8b49",
|
||||
"ssl": "\u4f7f\u7528 SSL \u8a8d\u8b49",
|
||||
"username": "\u4f7f\u7528\u8005\u540d\u7a31",
|
||||
"verify_ssl": "AdGuard Home \u4f7f\u7528\u5c0d\u61c9\u8a8d\u8b49"
|
||||
"verify_ssl": "\u78ba\u8a8d SSL \u8a8d\u8b49"
|
||||
},
|
||||
"description": "\u8a2d\u5b9a AdGuard Home \u4ee5\u9032\u884c\u76e3\u63a7\u3002"
|
||||
}
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
"""Support for ADS binary sensors."""
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.binary_sensor import (
|
||||
|
@ -14,8 +12,6 @@ import homeassistant.helpers.config_validation as cv
|
|||
|
||||
from . import CONF_ADS_VAR, DATA_ADS, STATE_KEY_STATE, AdsEntity
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DEFAULT_NAME = "ADS binary sensor"
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
||||
{
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
"""Support for ADS covers."""
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.cover import (
|
||||
|
@ -25,8 +23,6 @@ from . import (
|
|||
AdsEntity,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DEFAULT_NAME = "ADS Cover"
|
||||
|
||||
CONF_ADS_VAR_SET_POS = "adsvar_set_position"
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
"""Support for ADS light sources."""
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.light import (
|
||||
|
@ -21,7 +19,6 @@ from . import (
|
|||
AdsEntity,
|
||||
)
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
DEFAULT_NAME = "ADS Light"
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
||||
{
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
"""Support for ADS sensors."""
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components import ads
|
||||
|
@ -10,8 +8,6 @@ import homeassistant.helpers.config_validation as cv
|
|||
|
||||
from . import CONF_ADS_FACTOR, CONF_ADS_TYPE, CONF_ADS_VAR, STATE_KEY_STATE, AdsEntity
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DEFAULT_NAME = "ADS sensor"
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
||||
{
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
"""Support for ADS switch platform."""
|
||||
import logging
|
||||
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.components.switch import PLATFORM_SCHEMA, SwitchEntity
|
||||
|
@ -9,8 +7,6 @@ import homeassistant.helpers.config_validation as cv
|
|||
|
||||
from . import CONF_ADS_VAR, DATA_ADS, STATE_KEY_STATE, AdsEntity
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
DEFAULT_NAME = "ADS Switch"
|
||||
|
||||
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
|
||||
|
|
92
homeassistant/components/advantage_air/__init__.py
Normal file
92
homeassistant/components/advantage_air/__init__.py
Normal file
|
@ -0,0 +1,92 @@
|
|||
"""Advantage Air climate integration."""
|
||||
|
||||
import asyncio
|
||||
from datetime import timedelta
|
||||
import logging
|
||||
|
||||
from advantage_air import ApiError, advantage_air
|
||||
|
||||
from homeassistant.const import CONF_IP_ADDRESS, CONF_PORT
|
||||
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 ADVANTAGE_AIR_RETRY, DOMAIN
|
||||
|
||||
ADVANTAGE_AIR_SYNC_INTERVAL = 15
|
||||
ADVANTAGE_AIR_PLATFORMS = ["climate", "cover", "binary_sensor", "sensor", "switch"]
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def async_setup(hass, config):
|
||||
"""Set up Advantage Air integration."""
|
||||
hass.data[DOMAIN] = {}
|
||||
return True
|
||||
|
||||
|
||||
async def async_setup_entry(hass, entry):
|
||||
"""Set up Advantage Air config."""
|
||||
ip_address = entry.data[CONF_IP_ADDRESS]
|
||||
port = entry.data[CONF_PORT]
|
||||
api = advantage_air(
|
||||
ip_address,
|
||||
port=port,
|
||||
session=async_get_clientsession(hass),
|
||||
retry=ADVANTAGE_AIR_RETRY,
|
||||
)
|
||||
|
||||
async def async_get():
|
||||
try:
|
||||
return await api.async_get()
|
||||
except ApiError as err:
|
||||
raise UpdateFailed(err) from err
|
||||
|
||||
coordinator = DataUpdateCoordinator(
|
||||
hass,
|
||||
_LOGGER,
|
||||
name="Advantage Air",
|
||||
update_method=async_get,
|
||||
update_interval=timedelta(seconds=ADVANTAGE_AIR_SYNC_INTERVAL),
|
||||
)
|
||||
|
||||
async def async_change(change):
|
||||
try:
|
||||
if await api.async_change(change):
|
||||
await coordinator.async_refresh()
|
||||
except ApiError as err:
|
||||
_LOGGER.warning(err)
|
||||
|
||||
await coordinator.async_refresh()
|
||||
|
||||
if not coordinator.data:
|
||||
raise ConfigEntryNotReady
|
||||
|
||||
hass.data[DOMAIN][entry.entry_id] = {
|
||||
"coordinator": coordinator,
|
||||
"async_change": async_change,
|
||||
}
|
||||
|
||||
for platform in ADVANTAGE_AIR_PLATFORMS:
|
||||
hass.async_create_task(
|
||||
hass.config_entries.async_forward_entry_setup(entry, platform)
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
async def async_unload_entry(hass, entry):
|
||||
"""Unload Advantage Air Config."""
|
||||
unload_ok = all(
|
||||
await asyncio.gather(
|
||||
*[
|
||||
hass.config_entries.async_forward_entry_unload(entry, component)
|
||||
for component in ADVANTAGE_AIR_PLATFORMS
|
||||
]
|
||||
)
|
||||
)
|
||||
|
||||
if unload_ok:
|
||||
hass.data[DOMAIN].pop(entry.entry_id)
|
||||
|
||||
return unload_ok
|
75
homeassistant/components/advantage_air/binary_sensor.py
Normal file
75
homeassistant/components/advantage_air/binary_sensor.py
Normal file
|
@ -0,0 +1,75 @@
|
|||
"""Binary Sensor platform for Advantage Air integration."""
|
||||
|
||||
from homeassistant.components.binary_sensor import (
|
||||
DEVICE_CLASS_MOTION,
|
||||
DEVICE_CLASS_PROBLEM,
|
||||
BinarySensorEntity,
|
||||
)
|
||||
|
||||
from .const import DOMAIN as ADVANTAGE_AIR_DOMAIN
|
||||
from .entity import AdvantageAirEntity
|
||||
|
||||
PARALLEL_UPDATES = 0
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up AdvantageAir motion platform."""
|
||||
|
||||
instance = hass.data[ADVANTAGE_AIR_DOMAIN][config_entry.entry_id]
|
||||
|
||||
entities = []
|
||||
for ac_key, ac_device in instance["coordinator"].data["aircons"].items():
|
||||
entities.append(AdvantageAirZoneFilter(instance, ac_key))
|
||||
for zone_key, zone in ac_device["zones"].items():
|
||||
# Only add motion sensor when motion is enabled
|
||||
if zone["motionConfig"] >= 2:
|
||||
entities.append(AdvantageAirZoneMotion(instance, ac_key, zone_key))
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
class AdvantageAirZoneFilter(AdvantageAirEntity, BinarySensorEntity):
|
||||
"""Advantage Air Filter."""
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name."""
|
||||
return f'{self._ac["name"]} Filter'
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
"""Return a unique id."""
|
||||
return f'{self.coordinator.data["system"]["rid"]}-{self.ac_key}-filter'
|
||||
|
||||
@property
|
||||
def device_class(self):
|
||||
"""Return the device class of the vent."""
|
||||
return DEVICE_CLASS_PROBLEM
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return if filter needs cleaning."""
|
||||
return self._ac["filterCleanStatus"]
|
||||
|
||||
|
||||
class AdvantageAirZoneMotion(AdvantageAirEntity, BinarySensorEntity):
|
||||
"""Advantage Air Zone Motion."""
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name."""
|
||||
return f'{self._zone["name"]} Motion'
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
"""Return a unique id."""
|
||||
return f'{self.coordinator.data["system"]["rid"]}-{self.ac_key}-{self.zone_key}-motion'
|
||||
|
||||
@property
|
||||
def device_class(self):
|
||||
"""Return the device class of the vent."""
|
||||
return DEVICE_CLASS_MOTION
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return if motion is detect."""
|
||||
return self._zone["motion"]
|
235
homeassistant/components/advantage_air/climate.py
Normal file
235
homeassistant/components/advantage_air/climate.py
Normal file
|
@ -0,0 +1,235 @@
|
|||
"""Climate platform for Advantage Air integration."""
|
||||
|
||||
from homeassistant.components.climate import ClimateEntity
|
||||
from homeassistant.components.climate.const import (
|
||||
FAN_AUTO,
|
||||
FAN_HIGH,
|
||||
FAN_LOW,
|
||||
FAN_MEDIUM,
|
||||
HVAC_MODE_COOL,
|
||||
HVAC_MODE_DRY,
|
||||
HVAC_MODE_FAN_ONLY,
|
||||
HVAC_MODE_HEAT,
|
||||
HVAC_MODE_OFF,
|
||||
SUPPORT_FAN_MODE,
|
||||
SUPPORT_TARGET_TEMPERATURE,
|
||||
)
|
||||
from homeassistant.const import ATTR_TEMPERATURE, PRECISION_WHOLE, TEMP_CELSIUS
|
||||
|
||||
from .const import (
|
||||
ADVANTAGE_AIR_STATE_CLOSE,
|
||||
ADVANTAGE_AIR_STATE_OFF,
|
||||
ADVANTAGE_AIR_STATE_ON,
|
||||
ADVANTAGE_AIR_STATE_OPEN,
|
||||
DOMAIN as ADVANTAGE_AIR_DOMAIN,
|
||||
)
|
||||
from .entity import AdvantageAirEntity
|
||||
|
||||
ADVANTAGE_AIR_HVAC_MODES = {
|
||||
"heat": HVAC_MODE_HEAT,
|
||||
"cool": HVAC_MODE_COOL,
|
||||
"vent": HVAC_MODE_FAN_ONLY,
|
||||
"dry": HVAC_MODE_DRY,
|
||||
}
|
||||
HASS_HVAC_MODES = {v: k for k, v in ADVANTAGE_AIR_HVAC_MODES.items()}
|
||||
|
||||
ADVANTAGE_AIR_FAN_MODES = {
|
||||
"auto": FAN_AUTO,
|
||||
"low": FAN_LOW,
|
||||
"medium": FAN_MEDIUM,
|
||||
"high": FAN_HIGH,
|
||||
}
|
||||
HASS_FAN_MODES = {v: k for k, v in ADVANTAGE_AIR_FAN_MODES.items()}
|
||||
FAN_SPEEDS = {FAN_LOW: 30, FAN_MEDIUM: 60, FAN_HIGH: 100}
|
||||
|
||||
AC_HVAC_MODES = [
|
||||
HVAC_MODE_OFF,
|
||||
HVAC_MODE_COOL,
|
||||
HVAC_MODE_HEAT,
|
||||
HVAC_MODE_FAN_ONLY,
|
||||
HVAC_MODE_DRY,
|
||||
]
|
||||
ZONE_HVAC_MODES = [HVAC_MODE_OFF, HVAC_MODE_FAN_ONLY]
|
||||
|
||||
PARALLEL_UPDATES = 0
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up AdvantageAir climate platform."""
|
||||
|
||||
instance = hass.data[ADVANTAGE_AIR_DOMAIN][config_entry.entry_id]
|
||||
|
||||
entities = []
|
||||
for ac_key, ac_device in instance["coordinator"].data["aircons"].items():
|
||||
entities.append(AdvantageAirAC(instance, ac_key))
|
||||
for zone_key, zone in ac_device["zones"].items():
|
||||
# Only add zone climate control when zone is in temperature control
|
||||
if zone["type"] != 0:
|
||||
entities.append(AdvantageAirZone(instance, ac_key, zone_key))
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
class AdvantageAirClimateEntity(AdvantageAirEntity, ClimateEntity):
|
||||
"""AdvantageAir Climate class."""
|
||||
|
||||
@property
|
||||
def temperature_unit(self):
|
||||
"""Return the temperature unit."""
|
||||
return TEMP_CELSIUS
|
||||
|
||||
@property
|
||||
def target_temperature_step(self):
|
||||
"""Return the supported temperature step."""
|
||||
return PRECISION_WHOLE
|
||||
|
||||
@property
|
||||
def max_temp(self):
|
||||
"""Return the maximum supported temperature."""
|
||||
return 32
|
||||
|
||||
@property
|
||||
def min_temp(self):
|
||||
"""Return the minimum supported temperature."""
|
||||
return 16
|
||||
|
||||
|
||||
class AdvantageAirAC(AdvantageAirClimateEntity):
|
||||
"""AdvantageAir AC unit."""
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name."""
|
||||
return self._ac["name"]
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
"""Return a unique id."""
|
||||
return f'{self.coordinator.data["system"]["rid"]}-{self.ac_key}'
|
||||
|
||||
@property
|
||||
def target_temperature(self):
|
||||
"""Return the current target temperature."""
|
||||
return self._ac["setTemp"]
|
||||
|
||||
@property
|
||||
def hvac_mode(self):
|
||||
"""Return the current HVAC modes."""
|
||||
if self._ac["state"] == ADVANTAGE_AIR_STATE_ON:
|
||||
return ADVANTAGE_AIR_HVAC_MODES.get(self._ac["mode"])
|
||||
return HVAC_MODE_OFF
|
||||
|
||||
@property
|
||||
def hvac_modes(self):
|
||||
"""Return the supported HVAC modes."""
|
||||
return AC_HVAC_MODES
|
||||
|
||||
@property
|
||||
def fan_mode(self):
|
||||
"""Return the current fan modes."""
|
||||
return ADVANTAGE_AIR_FAN_MODES.get(self._ac["fan"])
|
||||
|
||||
@property
|
||||
def fan_modes(self):
|
||||
"""Return the supported fan modes."""
|
||||
return [FAN_AUTO, FAN_LOW, FAN_MEDIUM, FAN_HIGH]
|
||||
|
||||
@property
|
||||
def supported_features(self):
|
||||
"""Return the supported features."""
|
||||
return SUPPORT_TARGET_TEMPERATURE | SUPPORT_FAN_MODE
|
||||
|
||||
async def async_set_hvac_mode(self, hvac_mode):
|
||||
"""Set the HVAC Mode and State."""
|
||||
if hvac_mode == HVAC_MODE_OFF:
|
||||
await self.async_change(
|
||||
{self.ac_key: {"info": {"state": ADVANTAGE_AIR_STATE_OFF}}}
|
||||
)
|
||||
else:
|
||||
await self.async_change(
|
||||
{
|
||||
self.ac_key: {
|
||||
"info": {
|
||||
"state": ADVANTAGE_AIR_STATE_ON,
|
||||
"mode": HASS_HVAC_MODES.get(hvac_mode),
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
async def async_set_fan_mode(self, fan_mode):
|
||||
"""Set the Fan Mode."""
|
||||
await self.async_change(
|
||||
{self.ac_key: {"info": {"fan": HASS_FAN_MODES.get(fan_mode)}}}
|
||||
)
|
||||
|
||||
async def async_set_temperature(self, **kwargs):
|
||||
"""Set the Temperature."""
|
||||
temp = kwargs.get(ATTR_TEMPERATURE)
|
||||
await self.async_change({self.ac_key: {"info": {"setTemp": temp}}})
|
||||
|
||||
|
||||
class AdvantageAirZone(AdvantageAirClimateEntity):
|
||||
"""AdvantageAir Zone control."""
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name."""
|
||||
return self._zone["name"]
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
"""Return a unique id."""
|
||||
return f'{self.coordinator.data["system"]["rid"]}-{self.ac_key}-{self.zone_key}'
|
||||
|
||||
@property
|
||||
def current_temperature(self):
|
||||
"""Return the current temperature."""
|
||||
return self._zone["measuredTemp"]
|
||||
|
||||
@property
|
||||
def target_temperature(self):
|
||||
"""Return the target temperature."""
|
||||
return self._zone["setTemp"]
|
||||
|
||||
@property
|
||||
def hvac_mode(self):
|
||||
"""Return the current HVAC modes."""
|
||||
if self._zone["state"] == ADVANTAGE_AIR_STATE_OPEN:
|
||||
return HVAC_MODE_FAN_ONLY
|
||||
return HVAC_MODE_OFF
|
||||
|
||||
@property
|
||||
def hvac_modes(self):
|
||||
"""Return supported HVAC modes."""
|
||||
return ZONE_HVAC_MODES
|
||||
|
||||
@property
|
||||
def supported_features(self):
|
||||
"""Return the supported features."""
|
||||
return SUPPORT_TARGET_TEMPERATURE
|
||||
|
||||
async def async_set_hvac_mode(self, hvac_mode):
|
||||
"""Set the HVAC Mode and State."""
|
||||
if hvac_mode == HVAC_MODE_OFF:
|
||||
await self.async_change(
|
||||
{
|
||||
self.ac_key: {
|
||||
"zones": {self.zone_key: {"state": ADVANTAGE_AIR_STATE_CLOSE}}
|
||||
}
|
||||
}
|
||||
)
|
||||
else:
|
||||
await self.async_change(
|
||||
{
|
||||
self.ac_key: {
|
||||
"zones": {self.zone_key: {"state": ADVANTAGE_AIR_STATE_OPEN}}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
async def async_set_temperature(self, **kwargs):
|
||||
"""Set the Temperature."""
|
||||
temp = kwargs.get(ATTR_TEMPERATURE)
|
||||
await self.async_change(
|
||||
{self.ac_key: {"zones": {self.zone_key: {"setTemp": temp}}}}
|
||||
)
|
57
homeassistant/components/advantage_air/config_flow.py
Normal file
57
homeassistant/components/advantage_air/config_flow.py
Normal file
|
@ -0,0 +1,57 @@
|
|||
"""Config Flow for Advantage Air integration."""
|
||||
from advantage_air import ApiError, advantage_air
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant import config_entries
|
||||
from homeassistant.const import CONF_IP_ADDRESS, CONF_PORT
|
||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||
|
||||
from .const import ADVANTAGE_AIR_RETRY, DOMAIN
|
||||
|
||||
ADVANTAGE_AIR_DEFAULT_PORT = 2025
|
||||
|
||||
ADVANTAGE_AIR_SCHEMA = vol.Schema(
|
||||
{
|
||||
vol.Required(CONF_IP_ADDRESS): str,
|
||||
vol.Optional(CONF_PORT, default=ADVANTAGE_AIR_DEFAULT_PORT): int,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
class AdvantageAirConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
||||
"""Config Advantage Air API connection."""
|
||||
|
||||
VERSION = 1
|
||||
CONNECTION_CLASS = config_entries.CONN_CLASS_LOCAL_POLL
|
||||
DOMAIN = DOMAIN
|
||||
|
||||
async def async_step_user(self, user_input=None):
|
||||
"""Get configuration from the user."""
|
||||
errors = {}
|
||||
if user_input:
|
||||
ip_address = user_input[CONF_IP_ADDRESS]
|
||||
port = user_input[CONF_PORT]
|
||||
|
||||
try:
|
||||
data = await advantage_air(
|
||||
ip_address,
|
||||
port=port,
|
||||
session=async_get_clientsession(self.hass),
|
||||
retry=ADVANTAGE_AIR_RETRY,
|
||||
).async_get(1)
|
||||
except ApiError:
|
||||
errors["base"] = "cannot_connect"
|
||||
else:
|
||||
await self.async_set_unique_id(data["system"]["rid"])
|
||||
self._abort_if_unique_id_configured()
|
||||
|
||||
return self.async_create_entry(
|
||||
title=data["system"]["name"],
|
||||
data=user_input,
|
||||
)
|
||||
|
||||
return self.async_show_form(
|
||||
step_id="user",
|
||||
data_schema=ADVANTAGE_AIR_SCHEMA,
|
||||
errors=errors,
|
||||
)
|
7
homeassistant/components/advantage_air/const.py
Normal file
7
homeassistant/components/advantage_air/const.py
Normal file
|
@ -0,0 +1,7 @@
|
|||
"""Constants used by Advantage Air integration."""
|
||||
DOMAIN = "advantage_air"
|
||||
ADVANTAGE_AIR_RETRY = 5
|
||||
ADVANTAGE_AIR_STATE_OPEN = "open"
|
||||
ADVANTAGE_AIR_STATE_CLOSE = "close"
|
||||
ADVANTAGE_AIR_STATE_ON = "on"
|
||||
ADVANTAGE_AIR_STATE_OFF = "off"
|
116
homeassistant/components/advantage_air/cover.py
Normal file
116
homeassistant/components/advantage_air/cover.py
Normal file
|
@ -0,0 +1,116 @@
|
|||
"""Cover platform for Advantage Air integration."""
|
||||
|
||||
from homeassistant.components.cover import (
|
||||
ATTR_POSITION,
|
||||
DEVICE_CLASS_DAMPER,
|
||||
SUPPORT_CLOSE,
|
||||
SUPPORT_OPEN,
|
||||
SUPPORT_SET_POSITION,
|
||||
CoverEntity,
|
||||
)
|
||||
|
||||
from .const import (
|
||||
ADVANTAGE_AIR_STATE_CLOSE,
|
||||
ADVANTAGE_AIR_STATE_OPEN,
|
||||
DOMAIN as ADVANTAGE_AIR_DOMAIN,
|
||||
)
|
||||
from .entity import AdvantageAirEntity
|
||||
|
||||
PARALLEL_UPDATES = 0
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up AdvantageAir cover platform."""
|
||||
|
||||
instance = hass.data[ADVANTAGE_AIR_DOMAIN][config_entry.entry_id]
|
||||
|
||||
entities = []
|
||||
for ac_key, ac_device in instance["coordinator"].data["aircons"].items():
|
||||
for zone_key, zone in ac_device["zones"].items():
|
||||
# Only add zone vent controls when zone in vent control mode.
|
||||
if zone["type"] == 0:
|
||||
entities.append(AdvantageAirZoneVent(instance, ac_key, zone_key))
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
class AdvantageAirZoneVent(AdvantageAirEntity, CoverEntity):
|
||||
"""Advantage Air Cover Class."""
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name."""
|
||||
return f'{self._zone["name"]}'
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
"""Return a unique id."""
|
||||
return f'{self.coordinator.data["system"]["rid"]}-{self.ac_key}-{self.zone_key}'
|
||||
|
||||
@property
|
||||
def device_class(self):
|
||||
"""Return the device class of the vent."""
|
||||
return DEVICE_CLASS_DAMPER
|
||||
|
||||
@property
|
||||
def supported_features(self):
|
||||
"""Return the supported features."""
|
||||
return SUPPORT_OPEN | SUPPORT_CLOSE | SUPPORT_SET_POSITION
|
||||
|
||||
@property
|
||||
def is_closed(self):
|
||||
"""Return if vent is fully closed."""
|
||||
return self._zone["state"] == ADVANTAGE_AIR_STATE_CLOSE
|
||||
|
||||
@property
|
||||
def current_cover_position(self):
|
||||
"""Return vents current position as a percentage."""
|
||||
if self._zone["state"] == ADVANTAGE_AIR_STATE_OPEN:
|
||||
return self._zone["value"]
|
||||
return 0
|
||||
|
||||
async def async_open_cover(self, **kwargs):
|
||||
"""Fully open zone vent."""
|
||||
await self.async_change(
|
||||
{
|
||||
self.ac_key: {
|
||||
"zones": {
|
||||
self.zone_key: {"state": ADVANTAGE_AIR_STATE_OPEN, "value": 100}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
async def async_close_cover(self, **kwargs):
|
||||
"""Fully close zone vent."""
|
||||
await self.async_change(
|
||||
{
|
||||
self.ac_key: {
|
||||
"zones": {self.zone_key: {"state": ADVANTAGE_AIR_STATE_CLOSE}}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
async def async_set_cover_position(self, **kwargs):
|
||||
"""Change vent position."""
|
||||
position = round(kwargs[ATTR_POSITION] / 5) * 5
|
||||
if position == 0:
|
||||
await self.async_change(
|
||||
{
|
||||
self.ac_key: {
|
||||
"zones": {self.zone_key: {"state": ADVANTAGE_AIR_STATE_CLOSE}}
|
||||
}
|
||||
}
|
||||
)
|
||||
else:
|
||||
await self.async_change(
|
||||
{
|
||||
self.ac_key: {
|
||||
"zones": {
|
||||
self.zone_key: {
|
||||
"state": ADVANTAGE_AIR_STATE_OPEN,
|
||||
"value": position,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
35
homeassistant/components/advantage_air/entity.py
Normal file
35
homeassistant/components/advantage_air/entity.py
Normal file
|
@ -0,0 +1,35 @@
|
|||
"""Advantage Air parent entity class."""
|
||||
|
||||
from homeassistant.helpers.update_coordinator import CoordinatorEntity
|
||||
|
||||
from .const import DOMAIN
|
||||
|
||||
|
||||
class AdvantageAirEntity(CoordinatorEntity):
|
||||
"""Parent class for Advantage Air Entities."""
|
||||
|
||||
def __init__(self, instance, ac_key, zone_key=None):
|
||||
"""Initialize common aspects of an Advantage Air sensor."""
|
||||
super().__init__(instance["coordinator"])
|
||||
self.async_change = instance["async_change"]
|
||||
self.ac_key = ac_key
|
||||
self.zone_key = zone_key
|
||||
|
||||
@property
|
||||
def _ac(self):
|
||||
return self.coordinator.data["aircons"][self.ac_key]["info"]
|
||||
|
||||
@property
|
||||
def _zone(self):
|
||||
return self.coordinator.data["aircons"][self.ac_key]["zones"][self.zone_key]
|
||||
|
||||
@property
|
||||
def device_info(self):
|
||||
"""Return parent device information."""
|
||||
return {
|
||||
"identifiers": {(DOMAIN, self.coordinator.data["system"]["rid"])},
|
||||
"name": self.coordinator.data["system"]["name"],
|
||||
"manufacturer": "Advantage Air",
|
||||
"model": self.coordinator.data["system"]["sysType"],
|
||||
"sw_version": self.coordinator.data["system"]["myAppRev"],
|
||||
}
|
9
homeassistant/components/advantage_air/manifest.json
Normal file
9
homeassistant/components/advantage_air/manifest.json
Normal file
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"domain": "advantage_air",
|
||||
"name": "Advantage Air",
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/advantage_air",
|
||||
"codeowners": ["@Bre77"],
|
||||
"requirements": ["advantage_air==0.2.1"],
|
||||
"quality_scale": "platinum"
|
||||
}
|
152
homeassistant/components/advantage_air/sensor.py
Normal file
152
homeassistant/components/advantage_air/sensor.py
Normal file
|
@ -0,0 +1,152 @@
|
|||
"""Sensor platform for Advantage Air integration."""
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.const import PERCENTAGE
|
||||
from homeassistant.helpers import config_validation as cv, entity_platform
|
||||
|
||||
from .const import ADVANTAGE_AIR_STATE_OPEN, DOMAIN as ADVANTAGE_AIR_DOMAIN
|
||||
from .entity import AdvantageAirEntity
|
||||
|
||||
ADVANTAGE_AIR_SET_COUNTDOWN_VALUE = "minutes"
|
||||
ADVANTAGE_AIR_SET_COUNTDOWN_UNIT = "min"
|
||||
ADVANTAGE_AIR_SERVICE_SET_TIME_TO = "set_time_to"
|
||||
|
||||
PARALLEL_UPDATES = 0
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up AdvantageAir sensor platform."""
|
||||
|
||||
instance = hass.data[ADVANTAGE_AIR_DOMAIN][config_entry.entry_id]
|
||||
|
||||
entities = []
|
||||
for ac_key, ac_device in instance["coordinator"].data["aircons"].items():
|
||||
entities.append(AdvantageAirTimeTo(instance, ac_key, "On"))
|
||||
entities.append(AdvantageAirTimeTo(instance, ac_key, "Off"))
|
||||
for zone_key, zone in ac_device["zones"].items():
|
||||
# Only show damper sensors when zone is in temperature control
|
||||
if zone["type"] != 0:
|
||||
entities.append(AdvantageAirZoneVent(instance, ac_key, zone_key))
|
||||
# Only show wireless signal strength sensors when using wireless sensors
|
||||
if zone["rssi"] > 0:
|
||||
entities.append(AdvantageAirZoneSignal(instance, ac_key, zone_key))
|
||||
async_add_entities(entities)
|
||||
|
||||
platform = entity_platform.current_platform.get()
|
||||
platform.async_register_entity_service(
|
||||
ADVANTAGE_AIR_SERVICE_SET_TIME_TO,
|
||||
{vol.Required("minutes"): cv.positive_int},
|
||||
"set_time_to",
|
||||
)
|
||||
|
||||
|
||||
class AdvantageAirTimeTo(AdvantageAirEntity):
|
||||
"""Representation of Advantage Air timer control."""
|
||||
|
||||
def __init__(self, instance, ac_key, action):
|
||||
"""Initialize the Advantage Air timer control."""
|
||||
super().__init__(instance, ac_key)
|
||||
self.action = action
|
||||
self._time_key = f"countDownTo{self.action}"
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name."""
|
||||
return f'{self._ac["name"]} Time To {self.action}'
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
"""Return a unique id."""
|
||||
return f'{self.coordinator.data["system"]["rid"]}-{self.ac_key}-timeto{self.action}'
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Return the current value."""
|
||||
return self._ac[self._time_key]
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
"""Return the unit of measurement."""
|
||||
return ADVANTAGE_AIR_SET_COUNTDOWN_UNIT
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Return a representative icon of the timer."""
|
||||
if self._ac[self._time_key] > 0:
|
||||
return "mdi:timer-outline"
|
||||
return "mdi:timer-off-outline"
|
||||
|
||||
async def set_time_to(self, **kwargs):
|
||||
"""Set the timer value."""
|
||||
value = min(720, max(0, int(kwargs[ADVANTAGE_AIR_SET_COUNTDOWN_VALUE])))
|
||||
await self.async_change({self.ac_key: {"info": {self._time_key: value}}})
|
||||
|
||||
|
||||
class AdvantageAirZoneVent(AdvantageAirEntity):
|
||||
"""Representation of Advantage Air Zone Vent Sensor."""
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name."""
|
||||
return f'{self._zone["name"]} Vent'
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
"""Return a unique id."""
|
||||
return f'{self.coordinator.data["system"]["rid"]}-{self.ac_key}-{self.zone_key}-vent'
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Return the current value of the air vent."""
|
||||
if self._zone["state"] == ADVANTAGE_AIR_STATE_OPEN:
|
||||
return self._zone["value"]
|
||||
return 0
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
"""Return the percent sign."""
|
||||
return PERCENTAGE
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Return a representative icon."""
|
||||
if self._zone["state"] == ADVANTAGE_AIR_STATE_OPEN:
|
||||
return "mdi:fan"
|
||||
return "mdi:fan-off"
|
||||
|
||||
|
||||
class AdvantageAirZoneSignal(AdvantageAirEntity):
|
||||
"""Representation of Advantage Air Zone wireless signal sensor."""
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name."""
|
||||
return f'{self._zone["name"]} Signal'
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
"""Return a unique id."""
|
||||
return f'{self.coordinator.data["system"]["rid"]}-{self.ac_key}-{self.zone_key}-signal'
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Return the current value of the wireless signal."""
|
||||
return self._zone["rssi"]
|
||||
|
||||
@property
|
||||
def unit_of_measurement(self):
|
||||
"""Return the percent sign."""
|
||||
return PERCENTAGE
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Return a representative icon."""
|
||||
if self._zone["rssi"] >= 80:
|
||||
return "mdi:wifi-strength-4"
|
||||
if self._zone["rssi"] >= 60:
|
||||
return "mdi:wifi-strength-3"
|
||||
if self._zone["rssi"] >= 40:
|
||||
return "mdi:wifi-strength-2"
|
||||
if self._zone["rssi"] >= 20:
|
||||
return "mdi:wifi-strength-1"
|
||||
return "mdi:wifi-strength-outline"
|
9
homeassistant/components/advantage_air/services.yaml
Normal file
9
homeassistant/components/advantage_air/services.yaml
Normal file
|
@ -0,0 +1,9 @@
|
|||
set_time_to:
|
||||
description: Control timers to turn the system on or off after a set number of minutes
|
||||
fields:
|
||||
entity_id:
|
||||
description: Time To sensor entity
|
||||
example: "sensor.ac_time_to_on"
|
||||
minutes:
|
||||
description: Minutes until action
|
||||
example: "60"
|
22
homeassistant/components/advantage_air/strings.json
Normal file
22
homeassistant/components/advantage_air/strings.json
Normal file
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"config": {
|
||||
"flow_title": "Advantage Air Setup",
|
||||
"error": {
|
||||
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]"
|
||||
},
|
||||
"abort": {
|
||||
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
|
||||
},
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"ip_address": "[%key:common::config_flow::data::ip%]",
|
||||
"port": "[%key:common::config_flow::data::port%]"
|
||||
},
|
||||
"description": "Connect to the API of your Advantage Air wall mounted tablet.",
|
||||
"title": "Connect"
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "Advantage Air"
|
||||
}
|
58
homeassistant/components/advantage_air/switch.py
Normal file
58
homeassistant/components/advantage_air/switch.py
Normal file
|
@ -0,0 +1,58 @@
|
|||
"""Switch platform for Advantage Air integration."""
|
||||
|
||||
from homeassistant.helpers.entity import ToggleEntity
|
||||
|
||||
from .const import (
|
||||
ADVANTAGE_AIR_STATE_OFF,
|
||||
ADVANTAGE_AIR_STATE_ON,
|
||||
DOMAIN as ADVANTAGE_AIR_DOMAIN,
|
||||
)
|
||||
from .entity import AdvantageAirEntity
|
||||
|
||||
|
||||
async def async_setup_entry(hass, config_entry, async_add_entities):
|
||||
"""Set up AdvantageAir toggle platform."""
|
||||
|
||||
instance = hass.data[ADVANTAGE_AIR_DOMAIN][config_entry.entry_id]
|
||||
|
||||
entities = []
|
||||
for ac_key, ac_device in instance["coordinator"].data["aircons"].items():
|
||||
if ac_device["info"]["freshAirStatus"] != "none":
|
||||
entities.append(AdvantageAirFreshAir(instance, ac_key))
|
||||
async_add_entities(entities)
|
||||
|
||||
|
||||
class AdvantageAirFreshAir(AdvantageAirEntity, ToggleEntity):
|
||||
"""Representation of Advantage Air fresh air control."""
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name."""
|
||||
return f'{self._ac["name"]} Fresh Air'
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
"""Return a unique id."""
|
||||
return f'{self.coordinator.data["system"]["rid"]}-{self.ac_key}-freshair'
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return the fresh air status."""
|
||||
return self._ac["freshAirStatus"] == ADVANTAGE_AIR_STATE_ON
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Return a representative icon of the fresh air switch."""
|
||||
return "mdi:air-filter"
|
||||
|
||||
async def async_turn_on(self, **kwargs):
|
||||
"""Turn fresh air on."""
|
||||
await self.async_change(
|
||||
{self.ac_key: {"info": {"freshAirStatus": ADVANTAGE_AIR_STATE_ON}}}
|
||||
)
|
||||
|
||||
async def async_turn_off(self, **kwargs):
|
||||
"""Turn fresh air off."""
|
||||
await self.async_change(
|
||||
{self.ac_key: {"info": {"freshAirStatus": ADVANTAGE_AIR_STATE_OFF}}}
|
||||
)
|
22
homeassistant/components/advantage_air/translations/ca.json
Normal file
22
homeassistant/components/advantage_air/translations/ca.json
Normal file
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "El dispositiu ja est\u00e0 configurat"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Ha fallat la connexi\u00f3"
|
||||
},
|
||||
"flow_title": "Configuraci\u00f3 d'Advantage Air",
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"ip_address": "Adre\u00e7a IP",
|
||||
"port": "Port"
|
||||
},
|
||||
"description": "Connecta't a l'API de la tauleta d'Advantage Air.",
|
||||
"title": "Connecta"
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "Advantage Air"
|
||||
}
|
21
homeassistant/components/advantage_air/translations/cs.json
Normal file
21
homeassistant/components/advantage_air/translations/cs.json
Normal file
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Za\u0159\u00edzen\u00ed je ji\u017e nastaveno"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Nepoda\u0159ilo se p\u0159ipojit"
|
||||
},
|
||||
"flow_title": "Nastaven\u00ed Advantage Air",
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"ip_address": "IP adresa",
|
||||
"port": "Port"
|
||||
},
|
||||
"title": "P\u0159ipojit"
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "Advantage Air"
|
||||
}
|
13
homeassistant/components/advantage_air/translations/de.json
Normal file
13
homeassistant/components/advantage_air/translations/de.json
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"config": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"ip_address": "IP Adresse",
|
||||
"port": "Port"
|
||||
},
|
||||
"title": "Verbinden"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
22
homeassistant/components/advantage_air/translations/en.json
Normal file
22
homeassistant/components/advantage_air/translations/en.json
Normal file
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Device is already configured"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Failed to connect"
|
||||
},
|
||||
"flow_title": "Advantage Air Setup",
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"ip_address": "IP Address",
|
||||
"port": "Port"
|
||||
},
|
||||
"description": "Connect to the API of your Advantage Air wall mounted tablet.",
|
||||
"title": "Connect"
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "Advantage Air"
|
||||
}
|
22
homeassistant/components/advantage_air/translations/es.json
Normal file
22
homeassistant/components/advantage_air/translations/es.json
Normal file
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "El dispositivo ya est\u00e1 configurado"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "No se pudo conectar"
|
||||
},
|
||||
"flow_title": "Configuraci\u00f3n de Advantage Air",
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"ip_address": "Direcci\u00f3n IP",
|
||||
"port": "Puerto"
|
||||
},
|
||||
"description": "Con\u00e9ctate a la API de tu tableta de pared Advantage Air.",
|
||||
"title": "Conectar"
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "Advantage Air"
|
||||
}
|
22
homeassistant/components/advantage_air/translations/et.json
Normal file
22
homeassistant/components/advantage_air/translations/et.json
Normal file
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Seade on juba h\u00e4\u00e4lestatud"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "\u00dchendus nurjus"
|
||||
},
|
||||
"flow_title": "Advantage Air-i seadistamine",
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"ip_address": "IP aadress",
|
||||
"port": ""
|
||||
},
|
||||
"description": "\u00dchendu oma Advantage Air seinale paigaldatud tahvelarvuti API-ga.",
|
||||
"title": "\u00dchenda"
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": ""
|
||||
}
|
22
homeassistant/components/advantage_air/translations/it.json
Normal file
22
homeassistant/components/advantage_air/translations/it.json
Normal file
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"config": {
|
||||
"abort": {
|
||||
"already_configured": "Il dispositivo \u00e8 gi\u00e0 configurato"
|
||||
},
|
||||
"error": {
|
||||
"cannot_connect": "Impossibile connettersi"
|
||||
},
|
||||
"flow_title": "Configurazione di Advantage Air",
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"ip_address": "Indirizzo IP",
|
||||
"port": "Porta"
|
||||
},
|
||||
"description": "Connettiti all'API del tablet montato a parete di Advantage Air.",
|
||||
"title": "Connetti"
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "Advantage Air"
|
||||
}
|
13
homeassistant/components/advantage_air/translations/nl.json
Normal file
13
homeassistant/components/advantage_air/translations/nl.json
Normal file
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"config": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"port": "Poort"
|
||||
},
|
||||
"title": "Verbind"
|
||||
}
|
||||
}
|
||||
},
|
||||
"title": "Advantage Air"
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue