Merge pull request #42516 from home-assistant/rc

This commit is contained in:
Franck Nijhof 2020-10-28 20:01:21 +01:00 committed by GitHub
commit 9c0a2d69ff
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4273 changed files with 62799 additions and 27146 deletions

View file

@ -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

View file

@ -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",

View file

@ -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

View file

@ -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
View file

@ -88,7 +88,7 @@ venv
.venv
Pipfile*
share/*
Scripts/
/Scripts/
# vimmy stuff
*.swp

View file

@ -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)$

View file

@ -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

View file

@ -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.

View file

@ -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)"

View file

@ -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

Before After
Before After

View file

@ -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>

View file

@ -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]

View file

@ -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):

View file

@ -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."""

View file

@ -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],

View file

@ -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%]"
}
}
}

View file

@ -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": {

View file

@ -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"
}

View 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"
}
}
}

View file

@ -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": {

View file

@ -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"
}

View 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"
}
}
}
}

View file

@ -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": {

View file

@ -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": {

View file

@ -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": {

View file

@ -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."

View file

@ -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"
}

View file

@ -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": {

View file

@ -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": {

View file

@ -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": {

View file

@ -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%]"
}
}
},

View file

@ -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"

View file

@ -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"
}
}
}

View file

@ -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"

View file

@ -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"

View file

@ -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)."
},

View file

@ -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"

View file

@ -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"

View file

@ -0,0 +1,12 @@
{
"config": {
"step": {
"user": {
"data": {
"longitude": "Lengtegraad",
"name": "Naam"
}
}
}
}
}

View file

@ -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": ""

View file

@ -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"
}
}

View file

@ -0,0 +1,8 @@
{
"state": {
"accuweather__pressure_tendency": {
"falling": "Fallande",
"rising": "Stigande"
}
}
}

View file

@ -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"

View file

@ -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])

View file

@ -10,7 +10,7 @@
}
},
"abort": {
"all_configured": "No new Pulse hubs discovered."
"no_devices_found": "[%key:common::config_flow::abort::no_devices_found%]"
}
}
}
}

View file

@ -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": {

View file

@ -0,0 +1,7 @@
{
"config": {
"abort": {
"no_devices_found": "V s\u00edti nebyla nalezena \u017e\u00e1dn\u00e1 za\u0159\u00edzen\u00ed"
}
}
}

View file

@ -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": {

View file

@ -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": {

View 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": ""
}

View file

@ -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": {

View file

@ -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": {

View file

@ -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": {

View file

@ -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": {

View file

@ -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": {

View file

@ -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": {

View file

@ -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(

View file

@ -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

View file

@ -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%]"
}
}
}

View file

@ -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."
}

View file

@ -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"
}
}
}

View 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"
}
}
}

View file

@ -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."
}

View file

@ -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": {

View 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."
}
}
}
}

View file

@ -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": {

View file

@ -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."
}

View file

@ -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": {

View file

@ -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"

View file

@ -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."
}

View file

@ -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."
}

View file

@ -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."
}

View file

@ -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": {

View file

@ -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"
}

View file

@ -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(
{

View file

@ -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"

View file

@ -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(
{

View file

@ -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(
{

View file

@ -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(

View 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

View 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"]

View 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}}}}
)

View 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,
)

View 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"

View 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,
}
}
}
}
)

View 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"],
}

View 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"
}

View 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"

View 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"

View 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"
}

View 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}}}
)

View 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"
}

View 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"
}

View file

@ -0,0 +1,13 @@
{
"config": {
"step": {
"user": {
"data": {
"ip_address": "IP Adresse",
"port": "Port"
},
"title": "Verbinden"
}
}
}
}

View 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"
}

View 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"
}

View 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": ""
}

View 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"
}

View 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