Merge pull request #71297 from home-assistant/rc

This commit is contained in:
Franck Nijhof 2022-05-04 19:11:20 +02:00 committed by GitHub
commit 4196c4e81c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3633 changed files with 67814 additions and 28395 deletions

View File

@ -73,7 +73,6 @@ omit =
homeassistant/components/arest/binary_sensor.py homeassistant/components/arest/binary_sensor.py
homeassistant/components/arest/sensor.py homeassistant/components/arest/sensor.py
homeassistant/components/arest/switch.py homeassistant/components/arest/switch.py
homeassistant/components/arlo/*
homeassistant/components/arris_tg2492lg/* homeassistant/components/arris_tg2492lg/*
homeassistant/components/aruba/device_tracker.py homeassistant/components/aruba/device_tracker.py
homeassistant/components/arwn/sensor.py homeassistant/components/arwn/sensor.py
@ -83,9 +82,7 @@ omit =
homeassistant/components/aseko_pool_live/sensor.py homeassistant/components/aseko_pool_live/sensor.py
homeassistant/components/asterisk_cdr/mailbox.py homeassistant/components/asterisk_cdr/mailbox.py
homeassistant/components/asterisk_mbox/* homeassistant/components/asterisk_mbox/*
homeassistant/components/asuswrt/__init__.py
homeassistant/components/asuswrt/diagnostics.py homeassistant/components/asuswrt/diagnostics.py
homeassistant/components/asuswrt/router.py
homeassistant/components/aten_pe/* homeassistant/components/aten_pe/*
homeassistant/components/atome/* homeassistant/components/atome/*
homeassistant/components/aurora/__init__.py homeassistant/components/aurora/__init__.py
@ -120,6 +117,7 @@ omit =
homeassistant/components/bmw_connected_drive/__init__.py homeassistant/components/bmw_connected_drive/__init__.py
homeassistant/components/bmw_connected_drive/binary_sensor.py homeassistant/components/bmw_connected_drive/binary_sensor.py
homeassistant/components/bmw_connected_drive/button.py homeassistant/components/bmw_connected_drive/button.py
homeassistant/components/bmw_connected_drive/coordinator.py
homeassistant/components/bmw_connected_drive/device_tracker.py homeassistant/components/bmw_connected_drive/device_tracker.py
homeassistant/components/bmw_connected_drive/lock.py homeassistant/components/bmw_connected_drive/lock.py
homeassistant/components/bmw_connected_drive/notify.py homeassistant/components/bmw_connected_drive/notify.py
@ -215,7 +213,6 @@ omit =
homeassistant/components/devolo_home_control/subscriber.py homeassistant/components/devolo_home_control/subscriber.py
homeassistant/components/devolo_home_control/switch.py homeassistant/components/devolo_home_control/switch.py
homeassistant/components/digital_ocean/* homeassistant/components/digital_ocean/*
homeassistant/components/digitalloggers/switch.py
homeassistant/components/discogs/sensor.py homeassistant/components/discogs/sensor.py
homeassistant/components/discord/__init__.py homeassistant/components/discord/__init__.py
homeassistant/components/discord/notify.py homeassistant/components/discord/notify.py
@ -593,10 +590,6 @@ omit =
homeassistant/components/keyboard_remote/* homeassistant/components/keyboard_remote/*
homeassistant/components/kira/* homeassistant/components/kira/*
homeassistant/components/kiwi/lock.py homeassistant/components/kiwi/lock.py
homeassistant/components/knx/__init__.py
homeassistant/components/knx/climate.py
homeassistant/components/knx/cover.py
homeassistant/components/knx/notify.py
homeassistant/components/kodi/__init__.py homeassistant/components/kodi/__init__.py
homeassistant/components/kodi/browse_media.py homeassistant/components/kodi/browse_media.py
homeassistant/components/kodi/const.py homeassistant/components/kodi/const.py
@ -678,6 +671,9 @@ omit =
homeassistant/components/map/* homeassistant/components/map/*
homeassistant/components/mastodon/notify.py homeassistant/components/mastodon/notify.py
homeassistant/components/matrix/* homeassistant/components/matrix/*
homeassistant/components/meater/__init__.py
homeassistant/components/meater/const.py
homeassistant/components/meater/sensor.py
homeassistant/components/media_extractor/* homeassistant/components/media_extractor/*
homeassistant/components/mediaroom/media_player.py homeassistant/components/mediaroom/media_player.py
homeassistant/components/melcloud/__init__.py homeassistant/components/melcloud/__init__.py
@ -996,7 +992,8 @@ omit =
homeassistant/components/rtorrent/sensor.py homeassistant/components/rtorrent/sensor.py
homeassistant/components/russound_rio/media_player.py homeassistant/components/russound_rio/media_player.py
homeassistant/components/russound_rnet/media_player.py homeassistant/components/russound_rnet/media_player.py
homeassistant/components/sabnzbd/* homeassistant/components/sabnzbd/__init__.py
homeassistant/components/sabnzbd/sensor.py
homeassistant/components/saj/sensor.py homeassistant/components/saj/sensor.py
homeassistant/components/satel_integra/* homeassistant/components/satel_integra/*
homeassistant/components/schluter/* homeassistant/components/schluter/*
@ -1030,6 +1027,10 @@ omit =
homeassistant/components/sensibo/number.py homeassistant/components/sensibo/number.py
homeassistant/components/sensibo/select.py homeassistant/components/sensibo/select.py
homeassistant/components/sensibo/sensor.py homeassistant/components/sensibo/sensor.py
homeassistant/components/sensibo/update.py
homeassistant/components/senz/__init__.py
homeassistant/components/senz/api.py
homeassistant/components/senz/climate.py
homeassistant/components/serial/sensor.py homeassistant/components/serial/sensor.py
homeassistant/components/serial_pm/sensor.py homeassistant/components/serial_pm/sensor.py
homeassistant/components/sesame/lock.py homeassistant/components/sesame/lock.py
@ -1128,6 +1129,8 @@ omit =
homeassistant/components/spotify/media_player.py homeassistant/components/spotify/media_player.py
homeassistant/components/spotify/system_health.py homeassistant/components/spotify/system_health.py
homeassistant/components/spotify/util.py homeassistant/components/spotify/util.py
homeassistant/components/slimproto/__init__.py
homeassistant/components/slimproto/media_player.py
homeassistant/components/squeezebox/__init__.py homeassistant/components/squeezebox/__init__.py
homeassistant/components/squeezebox/browse_media.py homeassistant/components/squeezebox/browse_media.py
homeassistant/components/squeezebox/media_player.py homeassistant/components/squeezebox/media_player.py
@ -1177,6 +1180,7 @@ omit =
homeassistant/components/synology_dsm/camera.py homeassistant/components/synology_dsm/camera.py
homeassistant/components/synology_dsm/diagnostics.py homeassistant/components/synology_dsm/diagnostics.py
homeassistant/components/synology_dsm/common.py homeassistant/components/synology_dsm/common.py
homeassistant/components/synology_dsm/entity.py
homeassistant/components/synology_dsm/sensor.py homeassistant/components/synology_dsm/sensor.py
homeassistant/components/synology_dsm/service.py homeassistant/components/synology_dsm/service.py
homeassistant/components/synology_dsm/switch.py homeassistant/components/synology_dsm/switch.py
@ -1201,7 +1205,7 @@ omit =
homeassistant/components/tankerkoenig/const.py homeassistant/components/tankerkoenig/const.py
homeassistant/components/tankerkoenig/sensor.py homeassistant/components/tankerkoenig/sensor.py
homeassistant/components/tapsaff/binary_sensor.py homeassistant/components/tapsaff/binary_sensor.py
homeassistant/components/tautulli/const.py homeassistant/components/tautulli/__init__.py
homeassistant/components/tautulli/coordinator.py homeassistant/components/tautulli/coordinator.py
homeassistant/components/tautulli/sensor.py homeassistant/components/tautulli/sensor.py
homeassistant/components/ted5000/sensor.py homeassistant/components/ted5000/sensor.py
@ -1265,6 +1269,7 @@ omit =
homeassistant/components/tractive/__init__.py homeassistant/components/tractive/__init__.py
homeassistant/components/tractive/binary_sensor.py homeassistant/components/tractive/binary_sensor.py
homeassistant/components/tractive/device_tracker.py homeassistant/components/tractive/device_tracker.py
homeassistant/components/tractive/diagnostics.py
homeassistant/components/tractive/entity.py homeassistant/components/tractive/entity.py
homeassistant/components/tractive/sensor.py homeassistant/components/tractive/sensor.py
homeassistant/components/tractive/switch.py homeassistant/components/tractive/switch.py
@ -1276,6 +1281,9 @@ omit =
homeassistant/components/tradfri/light.py homeassistant/components/tradfri/light.py
homeassistant/components/tradfri/sensor.py homeassistant/components/tradfri/sensor.py
homeassistant/components/tradfri/switch.py homeassistant/components/tradfri/switch.py
homeassistant/components/trafikverket_ferry/__init__.py
homeassistant/components/trafikverket_ferry/coordinator.py
homeassistant/components/trafikverket_ferry/sensor.py
homeassistant/components/trafikverket_train/__init__.py homeassistant/components/trafikverket_train/__init__.py
homeassistant/components/trafikverket_train/sensor.py homeassistant/components/trafikverket_train/sensor.py
homeassistant/components/trafikverket_weatherstation/__init__.py homeassistant/components/trafikverket_weatherstation/__init__.py
@ -1365,6 +1373,7 @@ omit =
homeassistant/components/vicare/button.py homeassistant/components/vicare/button.py
homeassistant/components/vicare/climate.py homeassistant/components/vicare/climate.py
homeassistant/components/vicare/const.py homeassistant/components/vicare/const.py
homeassistant/components/vicare/diagnostics.py
homeassistant/components/vicare/__init__.py homeassistant/components/vicare/__init__.py
homeassistant/components/vicare/sensor.py homeassistant/components/vicare/sensor.py
homeassistant/components/vicare/water_heater.py homeassistant/components/vicare/water_heater.py
@ -1428,6 +1437,7 @@ omit =
homeassistant/components/xiaomi_miio/button.py homeassistant/components/xiaomi_miio/button.py
homeassistant/components/xiaomi_miio/device.py homeassistant/components/xiaomi_miio/device.py
homeassistant/components/xiaomi_miio/device_tracker.py homeassistant/components/xiaomi_miio/device_tracker.py
homeassistant/components/xiaomi_miio/diagnostics.py
homeassistant/components/xiaomi_miio/fan.py homeassistant/components/xiaomi_miio/fan.py
homeassistant/components/xiaomi_miio/gateway.py homeassistant/components/xiaomi_miio/gateway.py
homeassistant/components/xiaomi_miio/humidifier.py homeassistant/components/xiaomi_miio/humidifier.py
@ -1443,6 +1453,7 @@ omit =
homeassistant/components/yale_smart_alarm/__init__.py homeassistant/components/yale_smart_alarm/__init__.py
homeassistant/components/yale_smart_alarm/alarm_control_panel.py homeassistant/components/yale_smart_alarm/alarm_control_panel.py
homeassistant/components/yale_smart_alarm/binary_sensor.py homeassistant/components/yale_smart_alarm/binary_sensor.py
homeassistant/components/yale_smart_alarm/button.py
homeassistant/components/yale_smart_alarm/const.py homeassistant/components/yale_smart_alarm/const.py
homeassistant/components/yale_smart_alarm/coordinator.py homeassistant/components/yale_smart_alarm/coordinator.py
homeassistant/components/yale_smart_alarm/diagnostics.py homeassistant/components/yale_smart_alarm/diagnostics.py
@ -1452,6 +1463,7 @@ omit =
homeassistant/components/yamaha_musiccast/media_player.py homeassistant/components/yamaha_musiccast/media_player.py
homeassistant/components/yamaha_musiccast/number.py homeassistant/components/yamaha_musiccast/number.py
homeassistant/components/yamaha_musiccast/select.py homeassistant/components/yamaha_musiccast/select.py
homeassistant/components/yamaha_musiccast/switch.py
homeassistant/components/yandex_transport/* homeassistant/components/yandex_transport/*
homeassistant/components/yeelightsunflower/light.py homeassistant/components/yeelightsunflower/light.py
homeassistant/components/yi/camera.py homeassistant/components/yi/camera.py
@ -1489,6 +1501,7 @@ omit =
homeassistant/components/zwave_me/button.py homeassistant/components/zwave_me/button.py
homeassistant/components/zwave_me/cover.py homeassistant/components/zwave_me/cover.py
homeassistant/components/zwave_me/climate.py homeassistant/components/zwave_me/climate.py
homeassistant/components/zwave_me/fan.py
homeassistant/components/zwave_me/helpers.py homeassistant/components/zwave_me/helpers.py
homeassistant/components/zwave_me/light.py homeassistant/components/zwave_me/light.py
homeassistant/components/zwave_me/lock.py homeassistant/components/zwave_me/lock.py

View File

@ -11,7 +11,8 @@
"ms-python.vscode-pylance", "ms-python.vscode-pylance",
"visualstudioexptteam.vscodeintellicode", "visualstudioexptteam.vscodeintellicode",
"redhat.vscode-yaml", "redhat.vscode-yaml",
"esbenp.prettier-vscode" "esbenp.prettier-vscode",
"GitHub.vscode-pull-request-github"
], ],
// Please keep this file in sync with settings in home-assistant/.vscode/settings.default.json // Please keep this file in sync with settings in home-assistant/.vscode/settings.default.json
"settings": { "settings": {

View File

@ -78,12 +78,13 @@ body:
- type: textarea - type: textarea
attributes: attributes:
label: Diagnostics information label: Diagnostics information
placeholder: "drag-and-drop the diagnostics data file here (do not copy-and-paste the content)"
description: >- description: >-
Many integrations provide the ability to download diagnostic data Many integrations provide the ability to download diagnostic data
on the device page (and on the integration dashboard). on the device page (and on the integration dashboard).
**It would really help if you could download the diagnostics data for the device you are having issues with, **It would really help if you could download the diagnostics data for the device you are having issues with,
and drag-and-drop that file into the textbox below.** and <ins>drag-and-drop that file into the textbox below.</ins>**
It generally allows pinpointing defects and thus resolving issues faster. It generally allows pinpointing defects and thus resolving issues faster.
- type: textarea - type: textarea

View File

@ -24,12 +24,12 @@ jobs:
publish: ${{ steps.version.outputs.publish }} publish: ${{ steps.version.outputs.publish }}
steps: steps:
- name: Checkout the repository - name: Checkout the repository
uses: actions/checkout@v3.0.0 uses: actions/checkout@v3.0.2
with: with:
fetch-depth: 0 fetch-depth: 0
- name: Set up Python ${{ env.DEFAULT_PYTHON }} - name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v3.0.0 uses: actions/setup-python@v3.1.2
with: with:
python-version: ${{ env.DEFAULT_PYTHON }} python-version: ${{ env.DEFAULT_PYTHON }}
@ -67,10 +67,10 @@ jobs:
if: github.repository_owner == 'home-assistant' && needs.init.outputs.publish == 'true' if: github.repository_owner == 'home-assistant' && needs.init.outputs.publish == 'true'
steps: steps:
- name: Checkout the repository - name: Checkout the repository
uses: actions/checkout@v3.0.0 uses: actions/checkout@v3.0.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }} - name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v3.0.0 uses: actions/setup-python@v3.1.2
with: with:
python-version: ${{ env.DEFAULT_PYTHON }} python-version: ${{ env.DEFAULT_PYTHON }}
@ -100,11 +100,11 @@ jobs:
arch: ${{ fromJson(needs.init.outputs.architectures) }} arch: ${{ fromJson(needs.init.outputs.architectures) }}
steps: steps:
- name: Checkout the repository - name: Checkout the repository
uses: actions/checkout@v3.0.0 uses: actions/checkout@v3.0.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }} - name: Set up Python ${{ env.DEFAULT_PYTHON }}
if: needs.init.outputs.channel == 'dev' if: needs.init.outputs.channel == 'dev'
uses: actions/setup-python@v3.0.0 uses: actions/setup-python@v3.1.2
with: with:
python-version: ${{ env.DEFAULT_PYTHON }} python-version: ${{ env.DEFAULT_PYTHON }}
@ -173,7 +173,7 @@ jobs:
- tinker - tinker
steps: steps:
- name: Checkout the repository - name: Checkout the repository
uses: actions/checkout@v3.0.0 uses: actions/checkout@v3.0.2
- name: Set build additional args - name: Set build additional args
run: | run: |
@ -216,7 +216,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout the repository - name: Checkout the repository
uses: actions/checkout@v3.0.0 uses: actions/checkout@v3.0.2
- name: Initialize git - name: Initialize git
uses: home-assistant/actions/helpers/git-init@master uses: home-assistant/actions/helpers/git-init@master
@ -255,7 +255,7 @@ jobs:
- "homeassistant" - "homeassistant"
steps: steps:
- name: Checkout the repository - name: Checkout the repository
uses: actions/checkout@v3.0.0 uses: actions/checkout@v3.0.2
- name: Login to DockerHub - name: Login to DockerHub
if: matrix.registry == 'homeassistant' if: matrix.registry == 'homeassistant'

View File

@ -22,7 +22,7 @@ on:
env: env:
CACHE_VERSION: 9 CACHE_VERSION: 9
PIP_CACHE_VERSION: 3 PIP_CACHE_VERSION: 3
HA_SHORT_VERSION: 2022.4 HA_SHORT_VERSION: 2022.5
DEFAULT_PYTHON: 3.9 DEFAULT_PYTHON: 3.9
PRE_COMMIT_CACHE: ~/.cache/pre-commit PRE_COMMIT_CACHE: ~/.cache/pre-commit
PIP_CACHE: /tmp/pip-cache PIP_CACHE: /tmp/pip-cache
@ -51,7 +51,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Check out code from GitHub - name: Check out code from GitHub
uses: actions/checkout@v3.0.0 uses: actions/checkout@v3.0.2
- name: Filter for core changes - name: Filter for core changes
uses: dorny/paths-filter@v2.10.2 uses: dorny/paths-filter@v2.10.2
id: core id: core
@ -152,10 +152,10 @@ jobs:
pre-commit-key: ${{ steps.generate-pre-commit-key.outputs.key }} pre-commit-key: ${{ steps.generate-pre-commit-key.outputs.key }}
steps: steps:
- name: Check out code from GitHub - name: Check out code from GitHub
uses: actions/checkout@v3.0.0 uses: actions/checkout@v3.0.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }} - name: Set up Python ${{ env.DEFAULT_PYTHON }}
id: python id: python
uses: actions/setup-python@v3.0.0 uses: actions/setup-python@v3.1.2
with: with:
python-version: ${{ env.DEFAULT_PYTHON }} python-version: ${{ env.DEFAULT_PYTHON }}
- name: Generate partial Python venv restore key - name: Generate partial Python venv restore key
@ -172,7 +172,7 @@ jobs:
env.HA_SHORT_VERSION }}-$(date -u '+%Y-%m-%dT%H:%M:%s')" env.HA_SHORT_VERSION }}-$(date -u '+%Y-%m-%dT%H:%M:%s')"
- name: Restore base Python virtual environment - name: Restore base Python virtual environment
id: cache-venv id: cache-venv
uses: actions/cache@v3.0.0 uses: actions/cache@v3.0.2
with: with:
path: venv path: venv
key: >- key: >-
@ -189,7 +189,7 @@ jobs:
# ${{ runner.os }}-${{ steps.python.outputs.python-version }}-base-venv-${{ env.CACHE_VERSION }}- # ${{ runner.os }}-${{ steps.python.outputs.python-version }}-base-venv-${{ env.CACHE_VERSION }}-
- name: Restore pip wheel cache - name: Restore pip wheel cache
if: steps.cache-venv.outputs.cache-hit != 'true' if: steps.cache-venv.outputs.cache-hit != 'true'
uses: actions/cache@v3.0.0 uses: actions/cache@v3.0.2
with: with:
path: ${{ env.PIP_CACHE }} path: ${{ env.PIP_CACHE }}
key: >- key: >-
@ -212,7 +212,7 @@ jobs:
hashFiles('.pre-commit-config.yaml') }}" hashFiles('.pre-commit-config.yaml') }}"
- name: Restore pre-commit environment from cache - name: Restore pre-commit environment from cache
id: cache-precommit id: cache-precommit
uses: actions/cache@v3.0.0 uses: actions/cache@v3.0.2
with: with:
path: ${{ env.PRE_COMMIT_CACHE }} path: ${{ env.PRE_COMMIT_CACHE }}
key: >- key: >-
@ -233,15 +233,15 @@ jobs:
- prepare-base - prepare-base
steps: steps:
- name: Check out code from GitHub - name: Check out code from GitHub
uses: actions/checkout@v3.0.0 uses: actions/checkout@v3.0.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }} - name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v3.0.0 uses: actions/setup-python@v3.1.2
id: python id: python
with: with:
python-version: ${{ env.DEFAULT_PYTHON }} python-version: ${{ env.DEFAULT_PYTHON }}
- name: Restore base Python virtual environment - name: Restore base Python virtual environment
id: cache-venv id: cache-venv
uses: actions/cache@v3.0.0 uses: actions/cache@v3.0.2
with: with:
path: venv path: venv
key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
@ -253,7 +253,7 @@ jobs:
exit 1 exit 1
- name: Restore pre-commit environment from cache - name: Restore pre-commit environment from cache
id: cache-precommit id: cache-precommit
uses: actions/cache@v3.0.0 uses: actions/cache@v3.0.2
with: with:
path: ${{ env.PRE_COMMIT_CACHE }} path: ${{ env.PRE_COMMIT_CACHE }}
key: ${{ runner.os }}-${{ needs.prepare-base.outputs.pre-commit-key }} key: ${{ runner.os }}-${{ needs.prepare-base.outputs.pre-commit-key }}
@ -283,15 +283,15 @@ jobs:
- prepare-base - prepare-base
steps: steps:
- name: Check out code from GitHub - name: Check out code from GitHub
uses: actions/checkout@v3.0.0 uses: actions/checkout@v3.0.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }} - name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v3.0.0 uses: actions/setup-python@v3.1.2
id: python id: python
with: with:
python-version: ${{ env.DEFAULT_PYTHON }} python-version: ${{ env.DEFAULT_PYTHON }}
- name: Restore base Python virtual environment - name: Restore base Python virtual environment
id: cache-venv id: cache-venv
uses: actions/cache@v3.0.0 uses: actions/cache@v3.0.2
with: with:
path: venv path: venv
key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
@ -303,7 +303,7 @@ jobs:
exit 1 exit 1
- name: Restore pre-commit environment from cache - name: Restore pre-commit environment from cache
id: cache-precommit id: cache-precommit
uses: actions/cache@v3.0.0 uses: actions/cache@v3.0.2
with: with:
path: ${{ env.PRE_COMMIT_CACHE }} path: ${{ env.PRE_COMMIT_CACHE }}
key: ${{ runner.os }}-${{ needs.prepare-base.outputs.pre-commit-key }} key: ${{ runner.os }}-${{ needs.prepare-base.outputs.pre-commit-key }}
@ -334,15 +334,15 @@ jobs:
needs: prepare-base needs: prepare-base
steps: steps:
- name: Check out code from GitHub - name: Check out code from GitHub
uses: actions/checkout@v3.0.0 uses: actions/checkout@v3.0.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }} - name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v3.0.0 uses: actions/setup-python@v3.1.2
id: python id: python
with: with:
python-version: ${{ env.DEFAULT_PYTHON }} python-version: ${{ env.DEFAULT_PYTHON }}
- name: Restore base Python virtual environment - name: Restore base Python virtual environment
id: cache-venv id: cache-venv
uses: actions/cache@v3.0.0 uses: actions/cache@v3.0.2
with: with:
path: venv path: venv
key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
@ -354,7 +354,7 @@ jobs:
exit 1 exit 1
- name: Restore pre-commit environment from cache - name: Restore pre-commit environment from cache
id: cache-precommit id: cache-precommit
uses: actions/cache@v3.0.0 uses: actions/cache@v3.0.2
with: with:
path: ${{ env.PRE_COMMIT_CACHE }} path: ${{ env.PRE_COMMIT_CACHE }}
key: ${{ runner.os }}-${{ needs.prepare-base.outputs.pre-commit-key }} key: ${{ runner.os }}-${{ needs.prepare-base.outputs.pre-commit-key }}
@ -376,15 +376,15 @@ jobs:
- prepare-base - prepare-base
steps: steps:
- name: Check out code from GitHub - name: Check out code from GitHub
uses: actions/checkout@v3.0.0 uses: actions/checkout@v3.0.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }} - name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v3.0.0 uses: actions/setup-python@v3.1.2
id: python id: python
with: with:
python-version: ${{ env.DEFAULT_PYTHON }} python-version: ${{ env.DEFAULT_PYTHON }}
- name: Restore base Python virtual environment - name: Restore base Python virtual environment
id: cache-venv id: cache-venv
uses: actions/cache@v3.0.0 uses: actions/cache@v3.0.2
with: with:
path: venv path: venv
key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
@ -396,7 +396,7 @@ jobs:
exit 1 exit 1
- name: Restore pre-commit environment from cache - name: Restore pre-commit environment from cache
id: cache-precommit id: cache-precommit
uses: actions/cache@v3.0.0 uses: actions/cache@v3.0.2
with: with:
path: ${{ env.PRE_COMMIT_CACHE }} path: ${{ env.PRE_COMMIT_CACHE }}
key: ${{ runner.os }}-${{ needs.prepare-base.outputs.pre-commit-key }} key: ${{ runner.os }}-${{ needs.prepare-base.outputs.pre-commit-key }}
@ -435,11 +435,19 @@ jobs:
. venv/bin/activate . venv/bin/activate
pre-commit run --hook-stage manual check-json --all-files pre-commit run --hook-stage manual check-json --all-files
- name: Run prettier - name: Run prettier (fully)
if: needs.changes.outputs.test_full_suite == 'true'
run: | run: |
. venv/bin/activate . venv/bin/activate
pre-commit run --hook-stage manual prettier --all-files pre-commit run --hook-stage manual prettier --all-files
- name: Run prettier (partially)
if: needs.changes.outputs.test_full_suite == 'false'
shell: bash
run: |
. venv/bin/activate
pre-commit run --hook-stage manual prettier --files {homeassistant,tests}/components/${{ needs.changes.outputs.integrations_glob }}/**/*
- name: Register check executables problem matcher - name: Register check executables problem matcher
run: | run: |
echo "::add-matcher::.github/workflows/matchers/check-executables-have-shebangs.json" echo "::add-matcher::.github/workflows/matchers/check-executables-have-shebangs.json"
@ -491,10 +499,10 @@ jobs:
container: homeassistant/ci-azure:${{ matrix.python-version }} container: homeassistant/ci-azure:${{ matrix.python-version }}
steps: steps:
- name: Check out code from GitHub - name: Check out code from GitHub
uses: actions/checkout@v3.0.0 uses: actions/checkout@v3.0.2
- name: Restore full Python ${{ matrix.python-version }} virtual environment - name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv id: cache-venv
uses: actions/cache@v3.0.0 uses: actions/cache@v3.0.2
with: with:
path: venv path: venv
key: ${{ runner.os }}-${{ matrix.python-version }}-${{ key: ${{ runner.os }}-${{ matrix.python-version }}-${{
@ -515,15 +523,15 @@ jobs:
needs: prepare-base needs: prepare-base
steps: steps:
- name: Check out code from GitHub - name: Check out code from GitHub
uses: actions/checkout@v3.0.0 uses: actions/checkout@v3.0.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }} - name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v3.0.0 uses: actions/setup-python@v3.1.2
id: python id: python
with: with:
python-version: ${{ env.DEFAULT_PYTHON }} python-version: ${{ env.DEFAULT_PYTHON }}
- name: Restore base Python virtual environment - name: Restore base Python virtual environment
id: cache-venv id: cache-venv
uses: actions/cache@v3.0.0 uses: actions/cache@v3.0.2
with: with:
path: venv path: venv
key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{ key: ${{ runner.os }}-${{ steps.python.outputs.python-version }}-${{
@ -550,7 +558,7 @@ jobs:
container: homeassistant/ci-azure:${{ matrix.python-version }} container: homeassistant/ci-azure:${{ matrix.python-version }}
steps: steps:
- name: Check out code from GitHub - name: Check out code from GitHub
uses: actions/checkout@v3.0.0 uses: actions/checkout@v3.0.2
- name: Generate partial Python venv restore key - name: Generate partial Python venv restore key
id: generate-python-key id: generate-python-key
run: >- run: >-
@ -565,7 +573,7 @@ jobs:
env.HA_SHORT_VERSION }}-$(date -u '+%Y-%m-%dT%H:%M:%s')" env.HA_SHORT_VERSION }}-$(date -u '+%Y-%m-%dT%H:%M:%s')"
- name: Restore full Python ${{ matrix.python-version }} virtual environment - name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv id: cache-venv
uses: actions/cache@v3.0.0 uses: actions/cache@v3.0.2
with: with:
path: venv path: venv
key: >- key: >-
@ -582,7 +590,7 @@ jobs:
# ${{ runner.os }}-${{ matrix.python-version }}-venv-${{ env.CACHE_VERSION }}- # ${{ runner.os }}-${{ matrix.python-version }}-venv-${{ env.CACHE_VERSION }}-
- name: Restore pip wheel cache - name: Restore pip wheel cache
if: steps.cache-venv.outputs.cache-hit != 'true' if: steps.cache-venv.outputs.cache-hit != 'true'
uses: actions/cache@v3.0.0 uses: actions/cache@v3.0.2
with: with:
path: ${{ env.PIP_CACHE }} path: ${{ env.PIP_CACHE }}
key: >- key: >-
@ -618,10 +626,10 @@ jobs:
container: homeassistant/ci-azure:${{ matrix.python-version }} container: homeassistant/ci-azure:${{ matrix.python-version }}
steps: steps:
- name: Check out code from GitHub - name: Check out code from GitHub
uses: actions/checkout@v3.0.0 uses: actions/checkout@v3.0.2
- name: Restore full Python ${{ matrix.python-version }} virtual environment - name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv id: cache-venv
uses: actions/cache@v3.0.0 uses: actions/cache@v3.0.2
with: with:
path: venv path: venv
key: ${{ runner.os }}-${{ matrix.python-version }}-${{ key: ${{ runner.os }}-${{ matrix.python-version }}-${{
@ -660,10 +668,10 @@ jobs:
container: homeassistant/ci-azure:${{ matrix.python-version }} container: homeassistant/ci-azure:${{ matrix.python-version }}
steps: steps:
- name: Check out code from GitHub - name: Check out code from GitHub
uses: actions/checkout@v3.0.0 uses: actions/checkout@v3.0.2
- name: Restore full Python ${{ matrix.python-version }} virtual environment - name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv id: cache-venv
uses: actions/cache@v3.0.0 uses: actions/cache@v3.0.2
with: with:
path: venv path: venv
key: ${{ runner.os }}-${{ matrix.python-version }}-${{ key: ${{ runner.os }}-${{ matrix.python-version }}-${{
@ -704,10 +712,10 @@ jobs:
container: homeassistant/ci-azure:${{ matrix.python-version }} container: homeassistant/ci-azure:${{ matrix.python-version }}
steps: steps:
- name: Check out code from GitHub - name: Check out code from GitHub
uses: actions/checkout@v3.0.0 uses: actions/checkout@v3.0.2
- name: Restore full Python ${{ matrix.python-version }} virtual environment - name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv id: cache-venv
uses: actions/cache@v3.0.0 uses: actions/cache@v3.0.2
with: with:
path: venv path: venv
key: ${{ runner.os }}-${{ matrix.python-version }}-${{ key: ${{ runner.os }}-${{ matrix.python-version }}-${{
@ -747,10 +755,10 @@ jobs:
container: homeassistant/ci-azure:${{ matrix.python-version }} container: homeassistant/ci-azure:${{ matrix.python-version }}
steps: steps:
- name: Check out code from GitHub - name: Check out code from GitHub
uses: actions/checkout@v3.0.0 uses: actions/checkout@v3.0.2
- name: Restore full Python ${{ matrix.python-version }} virtual environment - name: Restore full Python ${{ matrix.python-version }} virtual environment
id: cache-venv id: cache-venv
uses: actions/cache@v3.0.0 uses: actions/cache@v3.0.2
with: with:
path: venv path: venv
key: ${{ runner.os }}-${{ matrix.python-version }}-${{ key: ${{ runner.os }}-${{ matrix.python-version }}-${{
@ -835,14 +843,14 @@ jobs:
- pytest - pytest
steps: steps:
- name: Check out code from GitHub - name: Check out code from GitHub
uses: actions/checkout@v3.0.0 uses: actions/checkout@v3.0.2
- name: Download all coverage artifacts - name: Download all coverage artifacts
uses: actions/download-artifact@v2 uses: actions/download-artifact@v3
- name: Upload coverage to Codecov (full coverage) - name: Upload coverage to Codecov (full coverage)
if: needs.changes.outputs.test_full_suite == 'true' if: needs.changes.outputs.test_full_suite == 'true'
uses: codecov/codecov-action@v2.1.0 uses: codecov/codecov-action@v3.1.0
with: with:
flags: full-suite flags: full-suite
- name: Upload coverage to Codecov (partial coverage) - name: Upload coverage to Codecov (partial coverage)
if: needs.changes.outputs.test_full_suite == 'false' if: needs.changes.outputs.test_full_suite == 'false'
uses: codecov/codecov-action@v2.1.0 uses: codecov/codecov-action@v3.1.0

View File

@ -8,6 +8,7 @@ on:
jobs: jobs:
stale: stale:
if: github.repository_owner == 'home-assistant'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
# The 90 day stale policy # The 90 day stale policy
@ -16,7 +17,7 @@ jobs:
# - No PRs marked as no-stale # - No PRs marked as no-stale
# - No issues marked as no-stale or help-wanted # - No issues marked as no-stale or help-wanted
- name: 90 days stale issues & PRs policy - name: 90 days stale issues & PRs policy
uses: actions/stale@v4 uses: actions/stale@v5
with: with:
repo-token: ${{ secrets.GITHUB_TOKEN }} repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 90 days-before-stale: 90
@ -53,7 +54,7 @@ jobs:
# - No PRs marked as no-stale or new-integrations # - No PRs marked as no-stale or new-integrations
# - No issues (-1) # - No issues (-1)
- name: 30 days stale PRs policy - name: 30 days stale PRs policy
uses: actions/stale@v4 uses: actions/stale@v5
with: with:
repo-token: ${{ secrets.GITHUB_TOKEN }} repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 30 days-before-stale: 30
@ -78,7 +79,7 @@ jobs:
# - No Issues marked as no-stale or help-wanted # - No Issues marked as no-stale or help-wanted
# - No PRs (-1) # - No PRs (-1)
- name: Needs more information stale issues policy - name: Needs more information stale issues policy
uses: actions/stale@v4 uses: actions/stale@v5
with: with:
repo-token: ${{ secrets.GITHUB_TOKEN }} repo-token: ${{ secrets.GITHUB_TOKEN }}
only-labels: "needs-more-information" only-labels: "needs-more-information"

View File

@ -21,10 +21,10 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout the repository - name: Checkout the repository
uses: actions/checkout@v3.0.0 uses: actions/checkout@v3.0.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }} - name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v3.0.0 uses: actions/setup-python@v3.1.2
with: with:
python-version: ${{ env.DEFAULT_PYTHON }} python-version: ${{ env.DEFAULT_PYTHON }}
@ -40,10 +40,10 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout the repository - name: Checkout the repository
uses: actions/checkout@v3.0.0 uses: actions/checkout@v3.0.2
- name: Set up Python ${{ env.DEFAULT_PYTHON }} - name: Set up Python ${{ env.DEFAULT_PYTHON }}
uses: actions/setup-python@v3.0.0 uses: actions/setup-python@v3.1.2
with: with:
python-version: ${{ env.DEFAULT_PYTHON }} python-version: ${{ env.DEFAULT_PYTHON }}

View File

@ -22,7 +22,7 @@ jobs:
architectures: ${{ steps.info.outputs.architectures }} architectures: ${{ steps.info.outputs.architectures }}
steps: steps:
- name: Checkout the repository - name: Checkout the repository
uses: actions/checkout@v3.0.0 uses: actions/checkout@v3.0.2
- name: Get information - name: Get information
id: info id: info
@ -74,15 +74,15 @@ jobs:
- "3.9-alpine3.14" - "3.9-alpine3.14"
steps: steps:
- name: Checkout the repository - name: Checkout the repository
uses: actions/checkout@v3.0.0 uses: actions/checkout@v3.0.2
- name: Download env_file - name: Download env_file
uses: actions/download-artifact@v2 uses: actions/download-artifact@v3
with: with:
name: env_file name: env_file
- name: Download requirements_diff - name: Download requirements_diff
uses: actions/download-artifact@v2 uses: actions/download-artifact@v3
with: with:
name: requirements_diff name: requirements_diff
@ -115,15 +115,15 @@ jobs:
- "3.9-alpine3.14" - "3.9-alpine3.14"
steps: steps:
- name: Checkout the repository - name: Checkout the repository
uses: actions/checkout@v3.0.0 uses: actions/checkout@v3.0.2
- name: Download env_file - name: Download env_file
uses: actions/download-artifact@v2 uses: actions/download-artifact@v3
with: with:
name: env_file name: env_file
- name: Download requirements_diff - name: Download requirements_diff
uses: actions/download-artifact@v2 uses: actions/download-artifact@v3
with: with:
name: requirements_diff name: requirements_diff

View File

@ -1,6 +1,6 @@
repos: repos:
- repo: https://github.com/asottile/pyupgrade - repo: https://github.com/asottile/pyupgrade
rev: v2.31.1 rev: v2.32.0
hooks: hooks:
- id: pyupgrade - id: pyupgrade
args: [--py39-plus] args: [--py39-plus]

View File

@ -46,6 +46,7 @@ homeassistant.components.ambient_station.*
homeassistant.components.amcrest.* homeassistant.components.amcrest.*
homeassistant.components.ampio.* homeassistant.components.ampio.*
homeassistant.components.aseko_pool_live.* homeassistant.components.aseko_pool_live.*
homeassistant.components.asuswrt.*
homeassistant.components.automation.* homeassistant.components.automation.*
homeassistant.components.backup.* homeassistant.components.backup.*
homeassistant.components.binary_sensor.* homeassistant.components.binary_sensor.*
@ -62,11 +63,7 @@ homeassistant.components.canary.*
homeassistant.components.cover.* homeassistant.components.cover.*
homeassistant.components.crownstone.* homeassistant.components.crownstone.*
homeassistant.components.cpuspeed.* homeassistant.components.cpuspeed.*
homeassistant.components.deconz homeassistant.components.deconz.*
homeassistant.components.deconz.config_flow
homeassistant.components.deconz.diagnostics
homeassistant.components.deconz.gateway
homeassistant.components.deconz.services
homeassistant.components.device_automation.* homeassistant.components.device_automation.*
homeassistant.components.device_tracker.* homeassistant.components.device_tracker.*
homeassistant.components.devolo_home_control.* homeassistant.components.devolo_home_control.*
@ -78,6 +75,7 @@ homeassistant.components.dsmr.*
homeassistant.components.dunehd.* homeassistant.components.dunehd.*
homeassistant.components.efergy.* homeassistant.components.efergy.*
homeassistant.components.elgato.* homeassistant.components.elgato.*
homeassistant.components.elkm1.*
homeassistant.components.esphome.* homeassistant.components.esphome.*
homeassistant.components.energy.* homeassistant.components.energy.*
homeassistant.components.evil_genius_labs.* homeassistant.components.evil_genius_labs.*
@ -88,6 +86,7 @@ homeassistant.components.flunearyou.*
homeassistant.components.flux_led.* homeassistant.components.flux_led.*
homeassistant.components.forecast_solar.* homeassistant.components.forecast_solar.*
homeassistant.components.fritzbox.* homeassistant.components.fritzbox.*
homeassistant.components.fritzbox_callmonitor.*
homeassistant.components.fronius.* homeassistant.components.fronius.*
homeassistant.components.frontend.* homeassistant.components.frontend.*
homeassistant.components.fritz.* homeassistant.components.fritz.*
@ -196,6 +195,7 @@ homeassistant.components.scene.*
homeassistant.components.select.* homeassistant.components.select.*
homeassistant.components.sensor.* homeassistant.components.sensor.*
homeassistant.components.senseme.* homeassistant.components.senseme.*
homeassistant.components.senz.*
homeassistant.components.shelly.* homeassistant.components.shelly.*
homeassistant.components.simplisafe.* homeassistant.components.simplisafe.*
homeassistant.components.slack.* homeassistant.components.slack.*

View File

@ -56,7 +56,6 @@ build.json @home-assistant/supervisor
/tests/components/alexa/ @home-assistant/cloud @ochlocracy /tests/components/alexa/ @home-assistant/cloud @ochlocracy
/homeassistant/components/almond/ @gcampax @balloob /homeassistant/components/almond/ @gcampax @balloob
/tests/components/almond/ @gcampax @balloob /tests/components/almond/ @gcampax @balloob
/homeassistant/components/alpha_vantage/ @fabaff
/homeassistant/components/ambee/ @frenck /homeassistant/components/ambee/ @frenck
/tests/components/ambee/ @frenck /tests/components/ambee/ @frenck
/homeassistant/components/amberelectric/ @madpilot /homeassistant/components/amberelectric/ @madpilot
@ -82,7 +81,6 @@ build.json @home-assistant/supervisor
/tests/components/aprs/ @PhilRW /tests/components/aprs/ @PhilRW
/homeassistant/components/arcam_fmj/ @elupus /homeassistant/components/arcam_fmj/ @elupus
/tests/components/arcam_fmj/ @elupus /tests/components/arcam_fmj/ @elupus
/homeassistant/components/arest/ @fabaff
/homeassistant/components/arris_tg2492lg/ @vanbalken /homeassistant/components/arris_tg2492lg/ @vanbalken
/homeassistant/components/aseko_pool_live/ @milanmeu /homeassistant/components/aseko_pool_live/ @milanmeu
/tests/components/aseko_pool_live/ @milanmeu /tests/components/aseko_pool_live/ @milanmeu
@ -121,7 +119,6 @@ build.json @home-assistant/supervisor
/homeassistant/components/beewi_smartclim/ @alemuro /homeassistant/components/beewi_smartclim/ @alemuro
/homeassistant/components/binary_sensor/ @home-assistant/core /homeassistant/components/binary_sensor/ @home-assistant/core
/tests/components/binary_sensor/ @home-assistant/core /tests/components/binary_sensor/ @home-assistant/core
/homeassistant/components/bitcoin/ @fabaff
/homeassistant/components/bizkaibus/ @UgaitzEtxebarria /homeassistant/components/bizkaibus/ @UgaitzEtxebarria
/homeassistant/components/blebox/ @bbx-a @bbx-jp /homeassistant/components/blebox/ @bbx-a @bbx-jp
/tests/components/blebox/ @bbx-a @bbx-jp /tests/components/blebox/ @bbx-a @bbx-jp
@ -253,7 +250,6 @@ build.json @home-assistant/supervisor
/homeassistant/components/dunehd/ @bieniu /homeassistant/components/dunehd/ @bieniu
/tests/components/dunehd/ @bieniu /tests/components/dunehd/ @bieniu
/homeassistant/components/dwd_weather_warnings/ @runningman84 @stephan192 @Hummel95 /homeassistant/components/dwd_weather_warnings/ @runningman84 @stephan192 @Hummel95
/homeassistant/components/dweet/ @fabaff
/homeassistant/components/dynalite/ @ziv1234 /homeassistant/components/dynalite/ @ziv1234
/tests/components/dynalite/ @ziv1234 /tests/components/dynalite/ @ziv1234
/homeassistant/components/eafm/ @Jc2k /homeassistant/components/eafm/ @Jc2k
@ -332,7 +328,6 @@ build.json @home-assistant/supervisor
/tests/components/flipr/ @cnico /tests/components/flipr/ @cnico
/homeassistant/components/flo/ @dmulcahey /homeassistant/components/flo/ @dmulcahey
/tests/components/flo/ @dmulcahey /tests/components/flo/ @dmulcahey
/homeassistant/components/flock/ @fabaff
/homeassistant/components/flume/ @ChrisMandich @bdraco /homeassistant/components/flume/ @ChrisMandich @bdraco
/tests/components/flume/ @ChrisMandich @bdraco /tests/components/flume/ @ChrisMandich @bdraco
/homeassistant/components/flunearyou/ @bachya /homeassistant/components/flunearyou/ @bachya
@ -354,6 +349,8 @@ build.json @home-assistant/supervisor
/tests/components/fritz/ @mammuth @AaronDavidSchneider @chemelli74 @mib1185 /tests/components/fritz/ @mammuth @AaronDavidSchneider @chemelli74 @mib1185
/homeassistant/components/fritzbox/ @mib1185 @flabbamann /homeassistant/components/fritzbox/ @mib1185 @flabbamann
/tests/components/fritzbox/ @mib1185 @flabbamann /tests/components/fritzbox/ @mib1185 @flabbamann
/homeassistant/components/fritzbox_callmonitor/ @cdce8p
/tests/components/fritzbox_callmonitor/ @cdce8p
/homeassistant/components/fronius/ @nielstron @farmio /homeassistant/components/fronius/ @nielstron @farmio
/tests/components/fronius/ @nielstron @farmio /tests/components/fronius/ @nielstron @farmio
/homeassistant/components/frontend/ @home-assistant/frontend /homeassistant/components/frontend/ @home-assistant/frontend
@ -381,9 +378,8 @@ build.json @home-assistant/supervisor
/tests/components/gios/ @bieniu /tests/components/gios/ @bieniu
/homeassistant/components/github/ @timmo001 @ludeeus /homeassistant/components/github/ @timmo001 @ludeeus
/tests/components/github/ @timmo001 @ludeeus /tests/components/github/ @timmo001 @ludeeus
/homeassistant/components/gitter/ @fabaff /homeassistant/components/glances/ @engrbm87
/homeassistant/components/glances/ @fabaff @engrbm87 /tests/components/glances/ @engrbm87
/tests/components/glances/ @fabaff @engrbm87
/homeassistant/components/goalzero/ @tkdrob /homeassistant/components/goalzero/ @tkdrob
/tests/components/goalzero/ @tkdrob /tests/components/goalzero/ @tkdrob
/homeassistant/components/gogogate2/ @vangorra @bdraco /homeassistant/components/gogogate2/ @vangorra @bdraco
@ -476,8 +472,8 @@ build.json @home-assistant/supervisor
/homeassistant/components/image_processing/ @home-assistant/core /homeassistant/components/image_processing/ @home-assistant/core
/tests/components/image_processing/ @home-assistant/core /tests/components/image_processing/ @home-assistant/core
/homeassistant/components/incomfort/ @zxdavb /homeassistant/components/incomfort/ @zxdavb
/homeassistant/components/influxdb/ @fabaff @mdegat01 /homeassistant/components/influxdb/ @mdegat01
/tests/components/influxdb/ @fabaff @mdegat01 /tests/components/influxdb/ @mdegat01
/homeassistant/components/input_boolean/ @home-assistant/core /homeassistant/components/input_boolean/ @home-assistant/core
/tests/components/input_boolean/ @home-assistant/core /tests/components/input_boolean/ @home-assistant/core
/homeassistant/components/input_button/ @home-assistant/core /homeassistant/components/input_button/ @home-assistant/core
@ -554,6 +550,7 @@ build.json @home-assistant/supervisor
/tests/components/lcn/ @alengwenus /tests/components/lcn/ @alengwenus
/homeassistant/components/lg_netcast/ @Drafteed /homeassistant/components/lg_netcast/ @Drafteed
/homeassistant/components/life360/ @pnbruckner /homeassistant/components/life360/ @pnbruckner
/homeassistant/components/lifx/ @Djelibeybi
/homeassistant/components/light/ @home-assistant/core /homeassistant/components/light/ @home-assistant/core
/tests/components/light/ @home-assistant/core /tests/components/light/ @home-assistant/core
/homeassistant/components/linux_battery/ @fabaff /homeassistant/components/linux_battery/ @fabaff
@ -588,6 +585,8 @@ build.json @home-assistant/supervisor
/homeassistant/components/matrix/ @tinloaf /homeassistant/components/matrix/ @tinloaf
/homeassistant/components/mazda/ @bdr99 /homeassistant/components/mazda/ @bdr99
/tests/components/mazda/ @bdr99 /tests/components/mazda/ @bdr99
/homeassistant/components/meater/ @Sotolotl @emontnemery
/tests/components/meater/ @Sotolotl @emontnemery
/homeassistant/components/media_player/ @home-assistant/core /homeassistant/components/media_player/ @home-assistant/core
/tests/components/media_player/ @home-assistant/core /tests/components/media_player/ @home-assistant/core
/homeassistant/components/media_source/ @hunterjm /homeassistant/components/media_source/ @hunterjm
@ -637,7 +636,6 @@ build.json @home-assistant/supervisor
/tests/components/motion_blinds/ @starkillerOG /tests/components/motion_blinds/ @starkillerOG
/homeassistant/components/motioneye/ @dermotduffy /homeassistant/components/motioneye/ @dermotduffy
/tests/components/motioneye/ @dermotduffy /tests/components/motioneye/ @dermotduffy
/homeassistant/components/mpd/ @fabaff
/homeassistant/components/mqtt/ @emontnemery /homeassistant/components/mqtt/ @emontnemery
/tests/components/mqtt/ @emontnemery /tests/components/mqtt/ @emontnemery
/homeassistant/components/msteams/ @peroyvind /homeassistant/components/msteams/ @peroyvind
@ -684,8 +682,6 @@ build.json @home-assistant/supervisor
/tests/components/nina/ @DeerMaximum /tests/components/nina/ @DeerMaximum
/homeassistant/components/nissan_leaf/ @filcole /homeassistant/components/nissan_leaf/ @filcole
/homeassistant/components/nmbs/ @thibmaek /homeassistant/components/nmbs/ @thibmaek
/homeassistant/components/no_ip/ @fabaff
/tests/components/no_ip/ @fabaff
/homeassistant/components/noaa_tides/ @jdelaney72 /homeassistant/components/noaa_tides/ @jdelaney72
/homeassistant/components/notify/ @home-assistant/core /homeassistant/components/notify/ @home-assistant/core
/tests/components/notify/ @home-assistant/core /tests/components/notify/ @home-assistant/core
@ -758,8 +754,8 @@ build.json @home-assistant/supervisor
/tests/components/persistent_notification/ @home-assistant/core /tests/components/persistent_notification/ @home-assistant/core
/homeassistant/components/philips_js/ @elupus /homeassistant/components/philips_js/ @elupus
/tests/components/philips_js/ @elupus /tests/components/philips_js/ @elupus
/homeassistant/components/pi_hole/ @fabaff @johnluetke @shenxn /homeassistant/components/pi_hole/ @johnluetke @shenxn
/tests/components/pi_hole/ @fabaff @johnluetke @shenxn /tests/components/pi_hole/ @johnluetke @shenxn
/homeassistant/components/picnic/ @corneyl /homeassistant/components/picnic/ @corneyl
/tests/components/picnic/ @corneyl /tests/components/picnic/ @corneyl
/homeassistant/components/pilight/ @trekky12 /homeassistant/components/pilight/ @trekky12
@ -793,13 +789,15 @@ build.json @home-assistant/supervisor
/tests/components/pure_energie/ @klaasnicolaas /tests/components/pure_energie/ @klaasnicolaas
/homeassistant/components/push/ @dgomes /homeassistant/components/push/ @dgomes
/tests/components/push/ @dgomes /tests/components/push/ @dgomes
/homeassistant/components/pvoutput/ @fabaff @frenck /homeassistant/components/pvoutput/ @frenck
/tests/components/pvoutput/ @fabaff @frenck /tests/components/pvoutput/ @frenck
/homeassistant/components/pvpc_hourly_pricing/ @azogue /homeassistant/components/pvpc_hourly_pricing/ @azogue
/tests/components/pvpc_hourly_pricing/ @azogue /tests/components/pvpc_hourly_pricing/ @azogue
/homeassistant/components/qbittorrent/ @geoffreylagaisse /homeassistant/components/qbittorrent/ @geoffreylagaisse
/homeassistant/components/qld_bushfire/ @exxamalte /homeassistant/components/qld_bushfire/ @exxamalte
/tests/components/qld_bushfire/ @exxamalte /tests/components/qld_bushfire/ @exxamalte
/homeassistant/components/qnap_qsw/ @Noltari
/tests/components/qnap_qsw/ @Noltari
/homeassistant/components/quantum_gateway/ @cisasteelersfan /homeassistant/components/quantum_gateway/ @cisasteelersfan
/homeassistant/components/qvr_pro/ @oblogic7 /homeassistant/components/qvr_pro/ @oblogic7
/homeassistant/components/qwikswitch/ @kellerza /homeassistant/components/qwikswitch/ @kellerza
@ -857,6 +855,8 @@ build.json @home-assistant/supervisor
/tests/components/rtsp_to_webrtc/ @allenporter /tests/components/rtsp_to_webrtc/ @allenporter
/homeassistant/components/ruckus_unleashed/ @gabe565 /homeassistant/components/ruckus_unleashed/ @gabe565
/tests/components/ruckus_unleashed/ @gabe565 /tests/components/ruckus_unleashed/ @gabe565
/homeassistant/components/sabnzbd/ @shaiu
/tests/components/sabnzbd/ @shaiu
/homeassistant/components/safe_mode/ @home-assistant/core /homeassistant/components/safe_mode/ @home-assistant/core
/tests/components/safe_mode/ @home-assistant/core /tests/components/safe_mode/ @home-assistant/core
/homeassistant/components/saj/ @fredericvl /homeassistant/components/saj/ @fredericvl
@ -887,6 +887,8 @@ build.json @home-assistant/supervisor
/tests/components/sensor/ @home-assistant/core /tests/components/sensor/ @home-assistant/core
/homeassistant/components/sentry/ @dcramer @frenck /homeassistant/components/sentry/ @dcramer @frenck
/tests/components/sentry/ @dcramer @frenck /tests/components/sentry/ @dcramer @frenck
/homeassistant/components/senz/ @milanmeu
/tests/components/senz/ @milanmeu
/homeassistant/components/serial/ @fabaff /homeassistant/components/serial/ @fabaff
/homeassistant/components/seven_segments/ @fabaff /homeassistant/components/seven_segments/ @fabaff
/homeassistant/components/sharkiq/ @JeffResc @funkybunch @AritroSaha10 /homeassistant/components/sharkiq/ @JeffResc @funkybunch @AritroSaha10
@ -915,6 +917,8 @@ build.json @home-assistant/supervisor
/homeassistant/components/sleepiq/ @mfugate1 @kbickar /homeassistant/components/sleepiq/ @mfugate1 @kbickar
/tests/components/sleepiq/ @mfugate1 @kbickar /tests/components/sleepiq/ @mfugate1 @kbickar
/homeassistant/components/slide/ @ualex73 /homeassistant/components/slide/ @ualex73
/homeassistant/components/slimproto/ @marcelveldt
/tests/components/slimproto/ @marcelveldt
/homeassistant/components/sma/ @kellerza @rklomp /homeassistant/components/sma/ @kellerza @rklomp
/tests/components/sma/ @kellerza @rklomp /tests/components/sma/ @kellerza @rklomp
/homeassistant/components/smappee/ @bsmappee /homeassistant/components/smappee/ @bsmappee
@ -929,8 +933,6 @@ build.json @home-assistant/supervisor
/homeassistant/components/smhi/ @gjohansson-ST /homeassistant/components/smhi/ @gjohansson-ST
/tests/components/smhi/ @gjohansson-ST /tests/components/smhi/ @gjohansson-ST
/homeassistant/components/sms/ @ocalvo /homeassistant/components/sms/ @ocalvo
/homeassistant/components/smtp/ @fabaff
/tests/components/smtp/ @fabaff
/homeassistant/components/solaredge/ @frenck /homeassistant/components/solaredge/ @frenck
/tests/components/solaredge/ @frenck /tests/components/solaredge/ @frenck
/homeassistant/components/solaredge_local/ @drobtravels @scheric /homeassistant/components/solaredge_local/ @drobtravels @scheric
@ -957,8 +959,8 @@ build.json @home-assistant/supervisor
/homeassistant/components/splunk/ @Bre77 /homeassistant/components/splunk/ @Bre77
/homeassistant/components/spotify/ @frenck /homeassistant/components/spotify/ @frenck
/tests/components/spotify/ @frenck /tests/components/spotify/ @frenck
/homeassistant/components/sql/ @dgomes /homeassistant/components/sql/ @dgomes @gjohansson-ST
/tests/components/sql/ @dgomes /tests/components/sql/ @dgomes @gjohansson-ST
/homeassistant/components/squeezebox/ @rajlaud /homeassistant/components/squeezebox/ @rajlaud
/tests/components/squeezebox/ @rajlaud /tests/components/squeezebox/ @rajlaud
/homeassistant/components/srp_energy/ @briglx /homeassistant/components/srp_energy/ @briglx
@ -967,6 +969,8 @@ build.json @home-assistant/supervisor
/tests/components/starline/ @anonym-tsk /tests/components/starline/ @anonym-tsk
/homeassistant/components/statistics/ @fabaff @ThomDietrich /homeassistant/components/statistics/ @fabaff @ThomDietrich
/tests/components/statistics/ @fabaff @ThomDietrich /tests/components/statistics/ @fabaff @ThomDietrich
/homeassistant/components/steam_online/ @tkdrob
/tests/components/steam_online/ @tkdrob
/homeassistant/components/steamist/ @bdraco /homeassistant/components/steamist/ @bdraco
/tests/components/steamist/ @bdraco /tests/components/steamist/ @bdraco
/homeassistant/components/stiebel_eltron/ @fucm /homeassistant/components/stiebel_eltron/ @fucm
@ -1002,7 +1006,6 @@ build.json @home-assistant/supervisor
/homeassistant/components/synology_dsm/ @hacf-fr @Quentame @mib1185 /homeassistant/components/synology_dsm/ @hacf-fr @Quentame @mib1185
/tests/components/synology_dsm/ @hacf-fr @Quentame @mib1185 /tests/components/synology_dsm/ @hacf-fr @Quentame @mib1185
/homeassistant/components/synology_srm/ @aerialls /homeassistant/components/synology_srm/ @aerialls
/homeassistant/components/syslog/ @fabaff
/homeassistant/components/system_bridge/ @timmo001 /homeassistant/components/system_bridge/ @timmo001
/tests/components/system_bridge/ @timmo001 /tests/components/system_bridge/ @timmo001
/homeassistant/components/tado/ @michaelarnauts @north3221 /homeassistant/components/tado/ @michaelarnauts @north3221
@ -1016,7 +1019,8 @@ build.json @home-assistant/supervisor
/homeassistant/components/tapsaff/ @bazwilliams /homeassistant/components/tapsaff/ @bazwilliams
/homeassistant/components/tasmota/ @emontnemery /homeassistant/components/tasmota/ @emontnemery
/tests/components/tasmota/ @emontnemery /tests/components/tasmota/ @emontnemery
/homeassistant/components/tautulli/ @ludeeus /homeassistant/components/tautulli/ @ludeeus @tkdrob
/tests/components/tautulli/ @ludeeus @tkdrob
/homeassistant/components/tellduslive/ @fredrike /homeassistant/components/tellduslive/ @fredrike
/tests/components/tellduslive/ @fredrike /tests/components/tellduslive/ @fredrike
/homeassistant/components/template/ @PhracturedBlue @tetienne @home-assistant/core /homeassistant/components/template/ @PhracturedBlue @tetienne @home-assistant/core
@ -1042,14 +1046,16 @@ build.json @home-assistant/supervisor
/tests/components/tomorrowio/ @raman325 /tests/components/tomorrowio/ @raman325
/homeassistant/components/totalconnect/ @austinmroczek /homeassistant/components/totalconnect/ @austinmroczek
/tests/components/totalconnect/ @austinmroczek /tests/components/totalconnect/ @austinmroczek
/homeassistant/components/tplink/ @rytilahti @thegardenmonkey /homeassistant/components/tplink/ @rytilahti @thegardenmonkey @bdraco
/tests/components/tplink/ @rytilahti @thegardenmonkey /tests/components/tplink/ @rytilahti @thegardenmonkey @bdraco
/homeassistant/components/traccar/ @ludeeus /homeassistant/components/traccar/ @ludeeus
/tests/components/traccar/ @ludeeus /tests/components/traccar/ @ludeeus
/homeassistant/components/trace/ @home-assistant/core /homeassistant/components/trace/ @home-assistant/core
/tests/components/trace/ @home-assistant/core /tests/components/trace/ @home-assistant/core
/homeassistant/components/tractive/ @Danielhiversen @zhulik @bieniu /homeassistant/components/tractive/ @Danielhiversen @zhulik @bieniu
/tests/components/tractive/ @Danielhiversen @zhulik @bieniu /tests/components/tractive/ @Danielhiversen @zhulik @bieniu
/homeassistant/components/trafikverket_ferry/ @gjohansson-ST
/tests/components/trafikverket_ferry/ @gjohansson-ST
/homeassistant/components/trafikverket_train/ @endor-force @gjohansson-ST /homeassistant/components/trafikverket_train/ @endor-force @gjohansson-ST
/tests/components/trafikverket_train/ @endor-force @gjohansson-ST /tests/components/trafikverket_train/ @endor-force @gjohansson-ST
/homeassistant/components/trafikverket_weatherstation/ @endor-force @gjohansson-ST /homeassistant/components/trafikverket_weatherstation/ @endor-force @gjohansson-ST
@ -1058,8 +1064,8 @@ build.json @home-assistant/supervisor
/tests/components/transmission/ @engrbm87 @JPHutchins /tests/components/transmission/ @engrbm87 @JPHutchins
/homeassistant/components/tts/ @pvizeli /homeassistant/components/tts/ @pvizeli
/tests/components/tts/ @pvizeli /tests/components/tts/ @pvizeli
/homeassistant/components/tuya/ @Tuya @zlinoliver @METISU @frenck /homeassistant/components/tuya/ @Tuya @zlinoliver @frenck
/tests/components/tuya/ @Tuya @zlinoliver @METISU @frenck /tests/components/tuya/ @Tuya @zlinoliver @frenck
/homeassistant/components/twentemilieu/ @frenck /homeassistant/components/twentemilieu/ @frenck
/tests/components/twentemilieu/ @frenck /tests/components/twentemilieu/ @frenck
/homeassistant/components/twinkly/ @dr1rrb @Robbie1221 /homeassistant/components/twinkly/ @dr1rrb @Robbie1221
@ -1076,8 +1082,6 @@ build.json @home-assistant/supervisor
/tests/components/upcloud/ @scop /tests/components/upcloud/ @scop
/homeassistant/components/update/ @home-assistant/core /homeassistant/components/update/ @home-assistant/core
/tests/components/update/ @home-assistant/core /tests/components/update/ @home-assistant/core
/homeassistant/components/updater/ @home-assistant/core
/tests/components/updater/ @home-assistant/core
/homeassistant/components/upnp/ @StevenLooman @ehendrix23 /homeassistant/components/upnp/ @StevenLooman @ehendrix23
/tests/components/upnp/ @StevenLooman @ehendrix23 /tests/components/upnp/ @StevenLooman @ehendrix23
/homeassistant/components/uptime/ @frenck /homeassistant/components/uptime/ @frenck
@ -1104,8 +1108,8 @@ build.json @home-assistant/supervisor
/homeassistant/components/verisure/ @frenck /homeassistant/components/verisure/ @frenck
/tests/components/verisure/ @frenck /tests/components/verisure/ @frenck
/homeassistant/components/versasense/ @flamm3blemuff1n /homeassistant/components/versasense/ @flamm3blemuff1n
/homeassistant/components/version/ @fabaff @ludeeus /homeassistant/components/version/ @ludeeus
/tests/components/version/ @fabaff @ludeeus /tests/components/version/ @ludeeus
/homeassistant/components/vesync/ @markperdue @webdjoe @thegardenmonkey /homeassistant/components/vesync/ @markperdue @webdjoe @thegardenmonkey
/tests/components/vesync/ @markperdue @webdjoe @thegardenmonkey /tests/components/vesync/ @markperdue @webdjoe @thegardenmonkey
/homeassistant/components/vicare/ @oischinger /homeassistant/components/vicare/ @oischinger

View File

@ -19,6 +19,7 @@ RUN \
libpcap-dev \ libpcap-dev \
libturbojpeg0 \ libturbojpeg0 \
git \ git \
cmake \
&& apt-get clean \ && apt-get clean \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*

View File

@ -147,9 +147,7 @@ class Data:
if not bcrypt.checkpw(password.encode(), user_hash): if not bcrypt.checkpw(password.encode(), user_hash):
raise InvalidAuth raise InvalidAuth
def hash_password( # pylint: disable=no-self-use def hash_password(self, password: str, for_storage: bool = False) -> bytes:
self, password: str, for_storage: bool = False
) -> bytes:
"""Encode a password.""" """Encode a password."""
hashed: bytes = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12)) hashed: bytes = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12))

View File

@ -4,10 +4,7 @@ from __future__ import annotations
from abodepy.devices.alarm import AbodeAlarm as AbodeAl from abodepy.devices.alarm import AbodeAlarm as AbodeAl
import homeassistant.components.alarm_control_panel as alarm import homeassistant.components.alarm_control_panel as alarm
from homeassistant.components.alarm_control_panel.const import ( from homeassistant.components.alarm_control_panel import AlarmControlPanelEntityFeature
SUPPORT_ALARM_ARM_AWAY,
SUPPORT_ALARM_ARM_HOME,
)
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ( from homeassistant.const import (
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_AWAY,
@ -38,7 +35,10 @@ class AbodeAlarm(AbodeDevice, alarm.AlarmControlPanelEntity):
_attr_icon = ICON _attr_icon = ICON
_attr_code_arm_required = False _attr_code_arm_required = False
_attr_supported_features = SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY _attr_supported_features = (
AlarmControlPanelEntityFeature.ARM_HOME
| AlarmControlPanelEntityFeature.ARM_AWAY
)
_device: AbodeAl _device: AbodeAl
@property @property

View File

@ -3,6 +3,9 @@
"abort": { "abort": {
"single_instance_allowed": "Ja configurat. Nom\u00e9s \u00e9s possible una sola configuraci\u00f3." "single_instance_allowed": "Ja configurat. Nom\u00e9s \u00e9s possible una sola configuraci\u00f3."
}, },
"create_entry": {
"default": "Alguns sensors no estan activats de manera predeterminada. Els pots activar des del registre d'entitats, despr\u00e9s de la configuraci\u00f3 de la integraci\u00f3.\nLa previsi\u00f3 meteorol\u00f2gica no est\u00e0 activada de manera predeterminada. Pots activar-la a les opcions de la integraci\u00f3."
},
"error": { "error": {
"cannot_connect": "Ha fallat la connexi\u00f3", "cannot_connect": "Ha fallat la connexi\u00f3",
"invalid_api_key": "Clau API inv\u00e0lida", "invalid_api_key": "Clau API inv\u00e0lida",

View File

@ -3,6 +3,9 @@
"abort": { "abort": {
"single_instance_allowed": "Bereits konfiguriert. Nur eine einzige Konfiguration m\u00f6glich." "single_instance_allowed": "Bereits konfiguriert. Nur eine einzige Konfiguration m\u00f6glich."
}, },
"create_entry": {
"default": "Einige Sensoren sind standardm\u00e4\u00dfig nicht aktiviert. Du kannst sie nach der Integrationskonfiguration in der Entit\u00e4tsregistrierung aktivieren.\nDie Wettervorhersage ist nicht standardm\u00e4\u00dfig aktiviert. Du kannst sie in den Integrationsoptionen aktivieren."
},
"error": { "error": {
"cannot_connect": "Verbindung fehlgeschlagen", "cannot_connect": "Verbindung fehlgeschlagen",
"invalid_api_key": "Ung\u00fcltiger API-Schl\u00fcssel", "invalid_api_key": "Ung\u00fcltiger API-Schl\u00fcssel",

View File

@ -3,6 +3,9 @@
"abort": { "abort": {
"single_instance_allowed": "\u0388\u03c7\u03b5\u03b9 \u03ae\u03b4\u03b7 \u03c1\u03c5\u03b8\u03bc\u03b9\u03c3\u03c4\u03b5\u03af. \u039c\u03cc\u03bd\u03bf \u03bc\u03af\u03b1 \u03b4\u03b9\u03b1\u03bc\u03cc\u03c1\u03c6\u03c9\u03c3\u03b7 \u03b5\u03af\u03bd\u03b1\u03b9 \u03b4\u03c5\u03bd\u03b1\u03c4\u03ae." "single_instance_allowed": "\u0388\u03c7\u03b5\u03b9 \u03ae\u03b4\u03b7 \u03c1\u03c5\u03b8\u03bc\u03b9\u03c3\u03c4\u03b5\u03af. \u039c\u03cc\u03bd\u03bf \u03bc\u03af\u03b1 \u03b4\u03b9\u03b1\u03bc\u03cc\u03c1\u03c6\u03c9\u03c3\u03b7 \u03b5\u03af\u03bd\u03b1\u03b9 \u03b4\u03c5\u03bd\u03b1\u03c4\u03ae."
}, },
"create_entry": {
"default": "\u039f\u03c1\u03b9\u03c3\u03bc\u03ad\u03bd\u03bf\u03b9 \u03b1\u03b9\u03c3\u03b8\u03b7\u03c4\u03ae\u03c1\u03b5\u03c2 \u03b4\u03b5\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03b7\u03bc\u03ad\u03bd\u03bf\u03b9 \u03b1\u03c0\u03cc \u03c0\u03c1\u03bf\u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae. \u039c\u03c0\u03bf\u03c1\u03b5\u03af\u03c4\u03b5 \u03bd\u03b1 \u03c4\u03b1 \u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03ae\u03c3\u03b5\u03c4\u03b5 \u03c3\u03c4\u03bf \u03bc\u03b7\u03c4\u03c1\u03ce\u03bf \u03bf\u03bd\u03c4\u03bf\u03c4\u03ae\u03c4\u03c9\u03bd \u03bc\u03b5\u03c4\u03ac \u03c4\u03b7 \u03b4\u03b9\u03b1\u03bc\u03cc\u03c1\u03c6\u03c9\u03c3\u03b7 \u03c4\u03b7\u03c2 \u03b5\u03bd\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b7\u03c2.\n \u0397 \u03c0\u03c1\u03cc\u03b3\u03bd\u03c9\u03c3\u03b7 \u03ba\u03b1\u03b9\u03c1\u03bf\u03cd \u03b4\u03b5\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03b7\u03bc\u03ad\u03bd\u03b7 \u03b1\u03c0\u03cc \u03c0\u03c1\u03bf\u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae. \u039c\u03c0\u03bf\u03c1\u03b5\u03af\u03c4\u03b5 \u03bd\u03b1 \u03c4\u03bf \u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03ae\u03c3\u03b5\u03c4\u03b5 \u03c3\u03c4\u03b9\u03c2 \u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ad\u03c2 \u03b5\u03bd\u03c3\u03c9\u03bc\u03ac\u03c4\u03c9\u03c3\u03b7\u03c2."
},
"error": { "error": {
"cannot_connect": "\u0391\u03c0\u03bf\u03c4\u03c5\u03c7\u03af\u03b1 \u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7\u03c2", "cannot_connect": "\u0391\u03c0\u03bf\u03c4\u03c5\u03c7\u03af\u03b1 \u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7\u03c2",
"invalid_api_key": "\u039c\u03b7 \u03ad\u03b3\u03ba\u03c5\u03c1\u03bf \u03ba\u03bb\u03b5\u03b9\u03b4\u03af API", "invalid_api_key": "\u039c\u03b7 \u03ad\u03b3\u03ba\u03c5\u03c1\u03bf \u03ba\u03bb\u03b5\u03b9\u03b4\u03af API",

View File

@ -3,6 +3,9 @@
"abort": { "abort": {
"single_instance_allowed": "Already configured. Only a single configuration possible." "single_instance_allowed": "Already configured. Only a single configuration possible."
}, },
"create_entry": {
"default": "Some 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."
},
"error": { "error": {
"cannot_connect": "Failed to connect", "cannot_connect": "Failed to connect",
"invalid_api_key": "Invalid API key", "invalid_api_key": "Invalid API key",

View File

@ -3,6 +3,9 @@
"abort": { "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."
}, },
"create_entry": {
"default": "M\u00f5ned andurid ei ole vaikimisi lubatud. Saad neid lubada \u00fcksuse registris p\u00e4rast sidumise seadistamist.\nIlmaprognoos ei ole vaikimisi lubatud. Saad selle lubada sidumise valikutes."
},
"error": { "error": {
"cannot_connect": "\u00dchendamine nurjus", "cannot_connect": "\u00dchendamine nurjus",
"invalid_api_key": "API v\u00f5ti on vale", "invalid_api_key": "API v\u00f5ti on vale",

View File

@ -3,6 +3,9 @@
"abort": { "abort": {
"single_instance_allowed": "D\u00e9j\u00e0 configur\u00e9. Une seule configuration possible." "single_instance_allowed": "D\u00e9j\u00e0 configur\u00e9. Une seule configuration possible."
}, },
"create_entry": {
"default": "Certains capteurs ne sont pas activ\u00e9s par d\u00e9faut. Vous pouvez les activer dans le registre des entit\u00e9s une fois la configuration de l'int\u00e9gration termin\u00e9e.\nLes pr\u00e9visions m\u00e9t\u00e9orologiques ne sont pas activ\u00e9es par d\u00e9faut. Vous pouvez les activer dans les options de l'int\u00e9gration."
},
"error": { "error": {
"cannot_connect": "\u00c9chec de connexion", "cannot_connect": "\u00c9chec de connexion",
"invalid_api_key": "Cl\u00e9 d'API non valide", "invalid_api_key": "Cl\u00e9 d'API non valide",
@ -16,7 +19,7 @@
"longitude": "Longitude", "longitude": "Longitude",
"name": "Nom" "name": "Nom"
}, },
"description": "Si vous avez besoin d'aide pour la configuration, consultez le site suivant : https://www.home-assistant.io/integrations/accuweather/\n\nCertains capteurs ne sont pas activ\u00e9s par d\u00e9faut. Vous pouvez les activer dans le registre des entit\u00e9s apr\u00e8s la configuration de l'int\u00e9gration.\nLes pr\u00e9visions m\u00e9t\u00e9orologiques ne sont pas activ\u00e9es par d\u00e9faut. Vous pouvez l'activer dans les options d'int\u00e9gration.", "description": "Si vous avez besoin d'aide pour la configuration, consultez\u00a0: https://www.home-assistant.io/integrations/accuweather/\n\nCertains capteurs ne sont pas activ\u00e9s par d\u00e9faut. Vous pouvez les activer dans le registre des entit\u00e9s une fois la configuration de l'int\u00e9gration termin\u00e9e.\nLes pr\u00e9visions m\u00e9t\u00e9orologiques ne sont pas activ\u00e9es par d\u00e9faut. Vous pouvez les activer dans les options de l'int\u00e9gration.",
"title": "AccuWeather" "title": "AccuWeather"
} }
} }

View File

@ -3,6 +3,9 @@
"abort": { "abort": {
"single_instance_allowed": "M\u00e1r konfigur\u00e1lva van. Csak egy konfigur\u00e1ci\u00f3 lehets\u00e9ges." "single_instance_allowed": "M\u00e1r konfigur\u00e1lva van. Csak egy konfigur\u00e1ci\u00f3 lehets\u00e9ges."
}, },
"create_entry": {
"default": "Egyes \u00e9rz\u00e9kel\u0151k alap\u00e9rtelmez\u00e9s szerint nincsenek enged\u00e9lyezve. Az integr\u00e1ci\u00f3s konfigur\u00e1ci\u00f3 ut\u00e1n enged\u00e9lyezheti \u0151ket az entit\u00e1s rendszerle\u00edr\u00f3 adatb\u00e1zis\u00e1ban.\nAz id\u0151j\u00e1r\u00e1s-el\u0151rejelz\u00e9s alap\u00e9rtelmez\u00e9s szerint nincs enged\u00e9lyezve. Ezt az integr\u00e1ci\u00f3s be\u00e1ll\u00edt\u00e1sokban enged\u00e9lyezheti."
},
"error": { "error": {
"cannot_connect": "Sikertelen csatlakoz\u00e1s", "cannot_connect": "Sikertelen csatlakoz\u00e1s",
"invalid_api_key": "\u00c9rv\u00e9nytelen API kulcs", "invalid_api_key": "\u00c9rv\u00e9nytelen API kulcs",
@ -14,7 +17,7 @@
"api_key": "API kulcs", "api_key": "API kulcs",
"latitude": "Sz\u00e9less\u00e9g", "latitude": "Sz\u00e9less\u00e9g",
"longitude": "Hossz\u00fas\u00e1g", "longitude": "Hossz\u00fas\u00e1g",
"name": "N\u00e9v" "name": "Elnevez\u00e9s"
}, },
"description": "Ha seg\u00edts\u00e9gre van sz\u00fcks\u00e9ge a konfigur\u00e1l\u00e1shoz, n\u00e9zze meg itt: https://www.home-assistant.io/integrations/accuweather/ \n\nEgyes \u00e9rz\u00e9kel\u0151k alap\u00e9rtelmez\u00e9s szerint nincsenek enged\u00e9lyezve. Az integr\u00e1ci\u00f3s konfigur\u00e1ci\u00f3 ut\u00e1n enged\u00e9lyezheti \u0151ket az entit\u00e1s-nyilv\u00e1ntart\u00e1sban.\nAz id\u0151j\u00e1r\u00e1s-el\u0151rejelz\u00e9s alap\u00e9rtelmez\u00e9s szerint nincs enged\u00e9lyezve. Ezt az integr\u00e1ci\u00f3s be\u00e1ll\u00edt\u00e1sokban enged\u00e9lyezheti.", "description": "Ha seg\u00edts\u00e9gre van sz\u00fcks\u00e9ge a konfigur\u00e1l\u00e1shoz, n\u00e9zze meg itt: https://www.home-assistant.io/integrations/accuweather/ \n\nEgyes \u00e9rz\u00e9kel\u0151k alap\u00e9rtelmez\u00e9s szerint nincsenek enged\u00e9lyezve. Az integr\u00e1ci\u00f3s konfigur\u00e1ci\u00f3 ut\u00e1n enged\u00e9lyezheti \u0151ket az entit\u00e1s-nyilv\u00e1ntart\u00e1sban.\nAz id\u0151j\u00e1r\u00e1s-el\u0151rejelz\u00e9s alap\u00e9rtelmez\u00e9s szerint nincs enged\u00e9lyezve. Ezt az integr\u00e1ci\u00f3s be\u00e1ll\u00edt\u00e1sokban enged\u00e9lyezheti.",
"title": "AccuWeather" "title": "AccuWeather"

View File

@ -3,6 +3,9 @@
"abort": { "abort": {
"single_instance_allowed": "Sudah dikonfigurasi. Hanya satu konfigurasi yang diizinkan." "single_instance_allowed": "Sudah dikonfigurasi. Hanya satu konfigurasi yang diizinkan."
}, },
"create_entry": {
"default": "Beberapa sensor tidak diaktifkan secara default. Anda dapat mengaktifkannya di registri entitas setelah konfigurasi integrasi.\nPrakiraan cuaca tidak diaktifkan secara default. Anda dapat mengaktifkannya di opsi integrasi."
},
"error": { "error": {
"cannot_connect": "Gagal terhubung", "cannot_connect": "Gagal terhubung",
"invalid_api_key": "Kunci API tidak valid", "invalid_api_key": "Kunci API tidak valid",

View File

@ -3,6 +3,9 @@
"abort": { "abort": {
"single_instance_allowed": "Gi\u00e0 configurato. \u00c8 possibile una sola configurazione." "single_instance_allowed": "Gi\u00e0 configurato. \u00c8 possibile una sola configurazione."
}, },
"create_entry": {
"default": "Alcuni sensori non sono abilitati per impostazione predefinita. Puoi abilitarli nel registro delle entit\u00e0 dopo la configurazione dell'integrazione.\nLe previsioni del tempo non sono abilitate per impostazione predefinita. Puoi abilitarlo nelle opzioni di integrazione."
},
"error": { "error": {
"cannot_connect": "Impossibile connettersi", "cannot_connect": "Impossibile connettersi",
"invalid_api_key": "Chiave API non valida", "invalid_api_key": "Chiave API non valida",

View File

@ -3,6 +3,9 @@
"abort": { "abort": {
"single_instance_allowed": "\u3059\u3067\u306b\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u3059\u3002\u5358\u4e00\u306e\u8a2d\u5b9a\u3057\u304b\u3067\u304d\u307e\u305b\u3093\u3002" "single_instance_allowed": "\u3059\u3067\u306b\u8a2d\u5b9a\u3055\u308c\u3066\u3044\u307e\u3059\u3002\u5358\u4e00\u306e\u8a2d\u5b9a\u3057\u304b\u3067\u304d\u307e\u305b\u3093\u3002"
}, },
"create_entry": {
"default": "\u4e00\u90e8\u306e\u30bb\u30f3\u30b5\u30fc\u306f\u3001\u30c7\u30d5\u30a9\u30eb\u30c8\u3067\u306f\u6709\u52b9\u306b\u306a\u3063\u3066\u3044\u307e\u305b\u3093\u3002\u30a4\u30f3\u30c6\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u306e\u69cb\u6210\u5f8c\u3001\u30a8\u30f3\u30c6\u30a3\u30c6\u30a3\u30ec\u30b8\u30b9\u30c8\u30ea\u3067\u305d\u308c\u3089\u3092\u6709\u52b9\u306b\u3067\u304d\u307e\u3059\u3002\n\u5929\u6c17\u4e88\u5831\u306f\u30c7\u30d5\u30a9\u30eb\u30c8\u3067\u306f\u6709\u52b9\u306b\u306a\u3063\u3066\u3044\u307e\u305b\u3093\u3002\u30a4\u30f3\u30c6\u30b0\u30ec\u30fc\u30b7\u30e7\u30f3\u306e\u30aa\u30d7\u30b7\u30e7\u30f3\u3067\u6709\u52b9\u306b\u3067\u304d\u307e\u3059\u3002"
},
"error": { "error": {
"cannot_connect": "\u63a5\u7d9a\u306b\u5931\u6557\u3057\u307e\u3057\u305f", "cannot_connect": "\u63a5\u7d9a\u306b\u5931\u6557\u3057\u307e\u3057\u305f",
"invalid_api_key": "\u7121\u52b9\u306aAPI\u30ad\u30fc", "invalid_api_key": "\u7121\u52b9\u306aAPI\u30ad\u30fc",

View File

@ -3,6 +3,9 @@
"abort": { "abort": {
"single_instance_allowed": "Al geconfigureerd. Slechts een enkele configuratie mogelijk." "single_instance_allowed": "Al geconfigureerd. Slechts een enkele configuratie mogelijk."
}, },
"create_entry": {
"default": "Sommige sensoren zijn standaard niet ingeschakeld. U kunt ze inschakelen in het entiteitenregister na de integratieconfiguratie.\nWeersvoorspelling is niet standaard ingeschakeld. U kunt deze inschakelen in de integratieopties."
},
"error": { "error": {
"cannot_connect": "Kan geen verbinding maken", "cannot_connect": "Kan geen verbinding maken",
"invalid_api_key": "API-sleutel", "invalid_api_key": "API-sleutel",

View File

@ -3,6 +3,9 @@
"abort": { "abort": {
"single_instance_allowed": "Allerede konfigurert. Bare \u00e9n enkelt konfigurasjon er mulig." "single_instance_allowed": "Allerede konfigurert. Bare \u00e9n enkelt konfigurasjon er mulig."
}, },
"create_entry": {
"default": "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 integreringsalternativene."
},
"error": { "error": {
"cannot_connect": "Tilkobling mislyktes", "cannot_connect": "Tilkobling mislyktes",
"invalid_api_key": "Ugyldig API-n\u00f8kkel", "invalid_api_key": "Ugyldig API-n\u00f8kkel",

View File

@ -3,6 +3,9 @@
"abort": { "abort": {
"single_instance_allowed": "Ju\u017c skonfigurowano. Mo\u017cliwa jest tylko jedna konfiguracja." "single_instance_allowed": "Ju\u017c skonfigurowano. Mo\u017cliwa jest tylko jedna konfiguracja."
}, },
"create_entry": {
"default": "Niekt\u00f3re sensory nie s\u0105 domy\u015blnie w\u0142\u0105czone. Mo\u017cesz je w\u0142\u0105czy\u0107 w rejestrze encji po skonfigurowaniu integracji.\nPrognoza pogody nie jest domy\u015blnie w\u0142\u0105czona. Mo\u017cesz to w\u0142\u0105czy\u0107 w opcjach integracji."
},
"error": { "error": {
"cannot_connect": "Nie mo\u017cna nawi\u0105za\u0107 po\u0142\u0105czenia", "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",

View File

@ -3,6 +3,9 @@
"abort": { "abort": {
"single_instance_allowed": "J\u00e1 configurado. Apenas uma configura\u00e7\u00e3o \u00e9 poss\u00edvel." "single_instance_allowed": "J\u00e1 configurado. Apenas uma configura\u00e7\u00e3o \u00e9 poss\u00edvel."
}, },
"create_entry": {
"default": "Alguns sensores n\u00e3o s\u00e3o ativados por padr\u00e3o. Voc\u00ea pode habilit\u00e1-los no registro da entidade ap\u00f3s a configura\u00e7\u00e3o da integra\u00e7\u00e3o.\n A previs\u00e3o do tempo n\u00e3o est\u00e1 habilitada por padr\u00e3o. Voc\u00ea pode habilit\u00e1-lo nas op\u00e7\u00f5es de integra\u00e7\u00e3o."
},
"error": { "error": {
"cannot_connect": "Falha ao conectar", "cannot_connect": "Falha ao conectar",
"invalid_api_key": "Chave de API inv\u00e1lida", "invalid_api_key": "Chave de API inv\u00e1lida",

View File

@ -3,6 +3,9 @@
"abort": { "abort": {
"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." "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."
}, },
"create_entry": {
"default": "\u041f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0435\u043d\u0441\u043e\u0440\u044b \u0441\u043a\u0440\u044b\u0442\u044b \u0438 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d \u043f\u0440\u043e\u0433\u043d\u043e\u0437 \u043f\u043e\u0433\u043e\u0434\u044b. \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043d\u0443\u0436\u043d\u044b\u0445 \u0441\u0435\u043d\u0441\u043e\u0440\u043e\u0432 \u0432 \u0440\u0435\u0435\u0441\u0442\u0440\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432 \u0438 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u043f\u0440\u043e\u0433\u043d\u043e\u0437 \u043f\u043e\u0433\u043e\u0434\u044b \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438."
},
"error": { "error": {
"cannot_connect": "\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f.", "cannot_connect": "\u041d\u0435 \u0443\u0434\u0430\u043b\u043e\u0441\u044c \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c\u0441\u044f.",
"invalid_api_key": "\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 API.", "invalid_api_key": "\u041d\u0435\u0432\u0435\u0440\u043d\u044b\u0439 \u043a\u043b\u044e\u0447 API.",

View File

@ -3,6 +3,9 @@
"abort": { "abort": {
"single_instance_allowed": "Zaten yap\u0131land\u0131r\u0131lm\u0131\u015f. Yaln\u0131zca tek bir konfig\u00fcrasyon m\u00fcmk\u00fcnd\u00fcr." "single_instance_allowed": "Zaten yap\u0131land\u0131r\u0131lm\u0131\u015f. Yaln\u0131zca tek bir konfig\u00fcrasyon m\u00fcmk\u00fcnd\u00fcr."
}, },
"create_entry": {
"default": "Baz\u0131 sens\u00f6rler varsay\u0131lan olarak etkin de\u011fildir. Bunlar\u0131, entegrasyon yap\u0131land\u0131rmas\u0131ndan sonra varl\u0131k kay\u0131t defterinde etkinle\u015ftirebilirsiniz.\n Hava tahmini varsay\u0131lan olarak etkin de\u011fildir. Entegrasyon se\u00e7eneklerinde etkinle\u015ftirebilirsiniz."
},
"error": { "error": {
"cannot_connect": "Ba\u011flanma hatas\u0131", "cannot_connect": "Ba\u011flanma hatas\u0131",
"invalid_api_key": "Ge\u00e7ersiz API anahtar\u0131", "invalid_api_key": "Ge\u00e7ersiz API anahtar\u0131",

View File

@ -3,6 +3,9 @@
"abort": { "abort": {
"single_instance_allowed": "\u5df2\u7d93\u8a2d\u5b9a\u5b8c\u6210\u3001\u50c5\u80fd\u8a2d\u5b9a\u4e00\u7d44\u88dd\u7f6e\u3002" "single_instance_allowed": "\u5df2\u7d93\u8a2d\u5b9a\u5b8c\u6210\u3001\u50c5\u80fd\u8a2d\u5b9a\u4e00\u7d44\u88dd\u7f6e\u3002"
}, },
"create_entry": {
"default": "\u90e8\u5206\u611f\u6e2c\u5668\u9810\u8a2d\u70ba\u4e0d\u555f\u7528\u72c0\u614b\u3002\u53ef\u4ee5\u7a0d\u5f8c\u65bc\u6574\u5408\u8a2d\u5b9a\u9801\u9762\u4e2d\u7684\u5be6\u9ad4\u8a3b\u518a\u8868\u9032\u884c\u555f\u7528\u3002\n\u5929\u6c23\u9810\u5831\u9810\u8a2d\u70ba\u4e0d\u555f\u7528\u3001\u53ef\u4ee5\u65bc\u6574\u5408\u9078\u9805\u4e2d\u9032\u884c\u555f\u7528\u3002"
},
"error": { "error": {
"cannot_connect": "\u9023\u7dda\u5931\u6557", "cannot_connect": "\u9023\u7dda\u5931\u6557",
"invalid_api_key": "API \u91d1\u9470\u7121\u6548", "invalid_api_key": "API \u91d1\u9470\u7121\u6548",

View File

@ -3,15 +3,8 @@ from __future__ import annotations
from homeassistant.components.cover import ( from homeassistant.components.cover import (
ATTR_POSITION, ATTR_POSITION,
SUPPORT_CLOSE,
SUPPORT_CLOSE_TILT,
SUPPORT_OPEN,
SUPPORT_OPEN_TILT,
SUPPORT_SET_POSITION,
SUPPORT_SET_TILT_POSITION,
SUPPORT_STOP,
SUPPORT_STOP_TILT,
CoverEntity, CoverEntity,
CoverEntityFeature,
) )
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback from homeassistant.core import HomeAssistant, callback
@ -79,14 +72,17 @@ class AcmedaCover(AcmedaBase, CoverEntity):
supported_features = 0 supported_features = 0
if self.current_cover_position is not None: if self.current_cover_position is not None:
supported_features |= ( supported_features |= (
SUPPORT_OPEN | SUPPORT_CLOSE | SUPPORT_STOP | SUPPORT_SET_POSITION CoverEntityFeature.OPEN
| CoverEntityFeature.CLOSE
| CoverEntityFeature.STOP
| CoverEntityFeature.SET_POSITION
) )
if self.current_cover_tilt_position is not None: if self.current_cover_tilt_position is not None:
supported_features |= ( supported_features |= (
SUPPORT_OPEN_TILT CoverEntityFeature.OPEN_TILT
| SUPPORT_CLOSE_TILT | CoverEntityFeature.CLOSE_TILT
| SUPPORT_STOP_TILT | CoverEntityFeature.STOP_TILT
| SUPPORT_SET_TILT_POSITION | CoverEntityFeature.SET_TILT_POSITION
) )
return supported_features return supported_features

View File

@ -7,11 +7,7 @@ from adax import Adax
from adax_local import Adax as AdaxLocal from adax_local import Adax as AdaxLocal
from homeassistant.components.climate import ClimateEntity from homeassistant.components.climate import ClimateEntity
from homeassistant.components.climate.const import ( from homeassistant.components.climate.const import ClimateEntityFeature, HVACMode
HVAC_MODE_HEAT,
HVAC_MODE_OFF,
SUPPORT_TARGET_TEMPERATURE,
)
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ( from homeassistant.const import (
ATTR_TEMPERATURE, ATTR_TEMPERATURE,
@ -65,10 +61,10 @@ async def async_setup_entry(
class AdaxDevice(ClimateEntity): class AdaxDevice(ClimateEntity):
"""Representation of a heater.""" """Representation of a heater."""
_attr_hvac_modes = [HVAC_MODE_HEAT, HVAC_MODE_OFF] _attr_hvac_modes = [HVACMode.HEAT, HVACMode.OFF]
_attr_max_temp = 35 _attr_max_temp = 35
_attr_min_temp = 5 _attr_min_temp = 5
_attr_supported_features = SUPPORT_TARGET_TEMPERATURE _attr_supported_features = ClimateEntityFeature.TARGET_TEMPERATURE
_attr_target_temperature_step = PRECISION_WHOLE _attr_target_temperature_step = PRECISION_WHOLE
_attr_temperature_unit = TEMP_CELSIUS _attr_temperature_unit = TEMP_CELSIUS
@ -86,12 +82,12 @@ class AdaxDevice(ClimateEntity):
async def async_set_hvac_mode(self, hvac_mode: str) -> None: async def async_set_hvac_mode(self, hvac_mode: str) -> None:
"""Set hvac mode.""" """Set hvac mode."""
if hvac_mode == HVAC_MODE_HEAT: if hvac_mode == HVACMode.HEAT:
temperature = max(self.min_temp, self.target_temperature or self.min_temp) temperature = max(self.min_temp, self.target_temperature or self.min_temp)
await self._adax_data_handler.set_room_target_temperature( await self._adax_data_handler.set_room_target_temperature(
self._device_id, temperature, True self._device_id, temperature, True
) )
elif hvac_mode == HVAC_MODE_OFF: elif hvac_mode == HVACMode.OFF:
await self._adax_data_handler.set_room_target_temperature( await self._adax_data_handler.set_room_target_temperature(
self._device_id, self.min_temp, False self._device_id, self.min_temp, False
) )
@ -116,10 +112,10 @@ class AdaxDevice(ClimateEntity):
self._attr_current_temperature = room.get("temperature") self._attr_current_temperature = room.get("temperature")
self._attr_target_temperature = room.get("targetTemperature") self._attr_target_temperature = room.get("targetTemperature")
if room["heatingEnabled"]: if room["heatingEnabled"]:
self._attr_hvac_mode = HVAC_MODE_HEAT self._attr_hvac_mode = HVACMode.HEAT
self._attr_icon = "mdi:radiator" self._attr_icon = "mdi:radiator"
else: else:
self._attr_hvac_mode = HVAC_MODE_OFF self._attr_hvac_mode = HVACMode.OFF
self._attr_icon = "mdi:radiator-off" self._attr_icon = "mdi:radiator-off"
return return
@ -127,11 +123,11 @@ class AdaxDevice(ClimateEntity):
class LocalAdaxDevice(ClimateEntity): class LocalAdaxDevice(ClimateEntity):
"""Representation of a heater.""" """Representation of a heater."""
_attr_hvac_modes = [HVAC_MODE_HEAT] _attr_hvac_modes = [HVACMode.HEAT]
_attr_hvac_mode = HVAC_MODE_HEAT _attr_hvac_mode = HVACMode.HEAT
_attr_max_temp = 35 _attr_max_temp = 35
_attr_min_temp = 5 _attr_min_temp = 5
_attr_supported_features = SUPPORT_TARGET_TEMPERATURE _attr_supported_features = ClimateEntityFeature.TARGET_TEMPERATURE
_attr_target_temperature_step = PRECISION_WHOLE _attr_target_temperature_step = PRECISION_WHOLE
_attr_temperature_unit = TEMP_CELSIUS _attr_temperature_unit = TEMP_CELSIUS

View File

@ -20,9 +20,9 @@
"local": { "local": {
"data": { "data": {
"wifi_pswd": "WiFi jelsz\u00f3", "wifi_pswd": "WiFi jelsz\u00f3",
"wifi_ssid": "WiFi ssid" "wifi_ssid": "Wi-Fi SSID"
}, },
"description": "\u00c1ll\u00edtsa vissza a f\u0171t\u0151berendez\u00e9st a + \u00e9s az OK gomb nyomvatart\u00e1s\u00e1val, m\u00edg a kijelz\u0151n a \"Reset\" (Vissza\u00e1ll\u00edt\u00e1s) felirat nem jelenik meg. Ezut\u00e1n nyomja meg \u00e9s tartsa lenyomva a f\u0171t\u0151berendez\u00e9s OK gombj\u00e1t, am\u00edg a k\u00e9k led villogni nem kezd, majd nyomja meg a K\u00fcld\u00e9s gombot. A f\u0171t\u0151berendez\u00e9s konfigur\u00e1l\u00e1sa n\u00e9h\u00e1ny percet vehet ig\u00e9nybe." "description": "\u00c1ll\u00edtsa vissza a f\u0171t\u0151berendez\u00e9st a + \u00e9s az OK gomb nyomvatart\u00e1s\u00e1val, m\u00edg a kijelz\u0151n a \"Reset\" (Vissza\u00e1ll\u00edt\u00e1s) felirat nem jelenik meg. Ezut\u00e1n nyomja meg \u00e9s tartsa lenyomva a f\u0171t\u0151berendez\u00e9s OK gombj\u00e1t, am\u00edg a k\u00e9k led villogni nem kezd, l\u00e9pjen tov\u00e1bb. A f\u0171t\u0151berendez\u00e9s konfigur\u00e1l\u00e1sa n\u00e9h\u00e1ny percet vehet ig\u00e9nybe."
}, },
"user": { "user": {
"data": { "data": {

View File

@ -31,7 +31,7 @@
"host": "Host", "host": "Host",
"password": "Wachtwoord" "password": "Wachtwoord"
}, },
"description": "Selecteer verbindingstype. Lokaal vereist verwarming met bluetooth" "description": "Selecteer verbindingstype. Lokaal vereist verwarming met Bluetooth."
} }
} }
} }

View File

@ -8,11 +8,8 @@ from homeassistant.components.cover import (
ATTR_POSITION, ATTR_POSITION,
DEVICE_CLASSES_SCHEMA, DEVICE_CLASSES_SCHEMA,
PLATFORM_SCHEMA, PLATFORM_SCHEMA,
SUPPORT_CLOSE,
SUPPORT_OPEN,
SUPPORT_SET_POSITION,
SUPPORT_STOP,
CoverEntity, CoverEntity,
CoverEntityFeature,
) )
from homeassistant.const import CONF_DEVICE_CLASS, CONF_NAME from homeassistant.const import CONF_DEVICE_CLASS, CONF_NAME
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
@ -117,11 +114,13 @@ class AdsCover(AdsEntity, CoverEntity):
self._ads_var_close = ads_var_close self._ads_var_close = ads_var_close
self._ads_var_stop = ads_var_stop self._ads_var_stop = ads_var_stop
self._attr_device_class = device_class self._attr_device_class = device_class
self._attr_supported_features = SUPPORT_OPEN | SUPPORT_CLOSE self._attr_supported_features = (
CoverEntityFeature.OPEN | CoverEntityFeature.CLOSE
)
if ads_var_stop is not None: if ads_var_stop is not None:
self._attr_supported_features |= SUPPORT_STOP self._attr_supported_features |= CoverEntityFeature.STOP
if ads_var_pos_set is not None: if ads_var_pos_set is not None:
self._attr_supported_features |= SUPPORT_SET_POSITION self._attr_supported_features |= CoverEntityFeature.SET_POSITION
async def async_added_to_hass(self): async def async_added_to_hass(self):
"""Register device notification.""" """Register device notification."""

View File

@ -7,7 +7,7 @@ import voluptuous as vol
from homeassistant.components.light import ( from homeassistant.components.light import (
ATTR_BRIGHTNESS, ATTR_BRIGHTNESS,
PLATFORM_SCHEMA, PLATFORM_SCHEMA,
SUPPORT_BRIGHTNESS, ColorMode,
LightEntity, LightEntity,
) )
from homeassistant.const import CONF_NAME from homeassistant.const import CONF_NAME
@ -60,7 +60,11 @@ class AdsLight(AdsEntity, LightEntity):
self._state_dict[STATE_KEY_BRIGHTNESS] = None self._state_dict[STATE_KEY_BRIGHTNESS] = None
self._ads_var_brightness = ads_var_brightness self._ads_var_brightness = ads_var_brightness
if ads_var_brightness is not None: if ads_var_brightness is not None:
self._attr_supported_features = SUPPORT_BRIGHTNESS self._attr_color_mode = ColorMode.BRIGHTNESS
self._attr_supported_color_modes = {ColorMode.BRIGHTNESS}
else:
self._attr_color_mode = ColorMode.ONOFF
self._attr_supported_color_modes = {ColorMode.ONOFF}
async def async_added_to_hass(self): async def async_added_to_hass(self):
"""Register device notification.""" """Register device notification."""

View File

@ -9,15 +9,8 @@ from homeassistant.components.climate.const import (
FAN_HIGH, FAN_HIGH,
FAN_LOW, FAN_LOW,
FAN_MEDIUM, FAN_MEDIUM,
HVAC_MODE_AUTO, ClimateEntityFeature,
HVAC_MODE_COOL, HVACMode,
HVAC_MODE_DRY,
HVAC_MODE_FAN_ONLY,
HVAC_MODE_HEAT,
HVAC_MODE_HEAT_COOL,
HVAC_MODE_OFF,
SUPPORT_FAN_MODE,
SUPPORT_TARGET_TEMPERATURE,
) )
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_TEMPERATURE, PRECISION_WHOLE, TEMP_CELSIUS from homeassistant.const import ATTR_TEMPERATURE, PRECISION_WHOLE, TEMP_CELSIUS
@ -35,20 +28,20 @@ from .const import (
from .entity import AdvantageAirEntity from .entity import AdvantageAirEntity
ADVANTAGE_AIR_HVAC_MODES = { ADVANTAGE_AIR_HVAC_MODES = {
"heat": HVAC_MODE_HEAT, "heat": HVACMode.HEAT,
"cool": HVAC_MODE_COOL, "cool": HVACMode.COOL,
"vent": HVAC_MODE_FAN_ONLY, "vent": HVACMode.FAN_ONLY,
"dry": HVAC_MODE_DRY, "dry": HVACMode.DRY,
"myauto": HVAC_MODE_AUTO, "myauto": HVACMode.AUTO,
} }
HASS_HVAC_MODES = {v: k for k, v in ADVANTAGE_AIR_HVAC_MODES.items()} HASS_HVAC_MODES = {v: k for k, v in ADVANTAGE_AIR_HVAC_MODES.items()}
AC_HVAC_MODES = [ AC_HVAC_MODES = [
HVAC_MODE_OFF, HVACMode.OFF,
HVAC_MODE_COOL, HVACMode.COOL,
HVAC_MODE_HEAT, HVACMode.HEAT,
HVAC_MODE_FAN_ONLY, HVACMode.FAN_ONLY,
HVAC_MODE_DRY, HVACMode.DRY,
] ]
ADVANTAGE_AIR_FAN_MODES = { ADVANTAGE_AIR_FAN_MODES = {
@ -61,7 +54,7 @@ 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} FAN_SPEEDS = {FAN_LOW: 30, FAN_MEDIUM: 60, FAN_HIGH: 100}
ADVANTAGE_AIR_SERVICE_SET_MYZONE = "set_myzone" ADVANTAGE_AIR_SERVICE_SET_MYZONE = "set_myzone"
ZONE_HVAC_MODES = [HVAC_MODE_OFF, HVAC_MODE_HEAT_COOL] ZONE_HVAC_MODES = [HVACMode.OFF, HVACMode.HEAT_COOL]
PARALLEL_UPDATES = 0 PARALLEL_UPDATES = 0
@ -108,7 +101,9 @@ class AdvantageAirAC(AdvantageAirClimateEntity):
_attr_fan_modes = [FAN_AUTO, FAN_LOW, FAN_MEDIUM, FAN_HIGH] _attr_fan_modes = [FAN_AUTO, FAN_LOW, FAN_MEDIUM, FAN_HIGH]
_attr_hvac_modes = AC_HVAC_MODES _attr_hvac_modes = AC_HVAC_MODES
_attr_supported_features = SUPPORT_TARGET_TEMPERATURE | SUPPORT_FAN_MODE _attr_supported_features = (
ClimateEntityFeature.TARGET_TEMPERATURE | ClimateEntityFeature.FAN_MODE
)
def __init__(self, instance, ac_key): def __init__(self, instance, ac_key):
"""Initialize an AdvantageAir AC unit.""" """Initialize an AdvantageAir AC unit."""
@ -116,7 +111,7 @@ class AdvantageAirAC(AdvantageAirClimateEntity):
self._attr_name = self._ac["name"] self._attr_name = self._ac["name"]
self._attr_unique_id = f'{self.coordinator.data["system"]["rid"]}-{ac_key}' self._attr_unique_id = f'{self.coordinator.data["system"]["rid"]}-{ac_key}'
if self._ac.get("myAutoModeEnabled"): if self._ac.get("myAutoModeEnabled"):
self._attr_hvac_modes = AC_HVAC_MODES + [HVAC_MODE_AUTO] self._attr_hvac_modes = AC_HVAC_MODES + [HVACMode.AUTO]
@property @property
def target_temperature(self): def target_temperature(self):
@ -128,7 +123,7 @@ class AdvantageAirAC(AdvantageAirClimateEntity):
"""Return the current HVAC modes.""" """Return the current HVAC modes."""
if self._ac["state"] == ADVANTAGE_AIR_STATE_ON: if self._ac["state"] == ADVANTAGE_AIR_STATE_ON:
return ADVANTAGE_AIR_HVAC_MODES.get(self._ac["mode"]) return ADVANTAGE_AIR_HVAC_MODES.get(self._ac["mode"])
return HVAC_MODE_OFF return HVACMode.OFF
@property @property
def fan_mode(self): def fan_mode(self):
@ -137,7 +132,7 @@ class AdvantageAirAC(AdvantageAirClimateEntity):
async def async_set_hvac_mode(self, hvac_mode): async def async_set_hvac_mode(self, hvac_mode):
"""Set the HVAC Mode and State.""" """Set the HVAC Mode and State."""
if hvac_mode == HVAC_MODE_OFF: if hvac_mode == HVACMode.OFF:
await self.async_change( await self.async_change(
{self.ac_key: {"info": {"state": ADVANTAGE_AIR_STATE_OFF}}} {self.ac_key: {"info": {"state": ADVANTAGE_AIR_STATE_OFF}}}
) )
@ -169,7 +164,7 @@ class AdvantageAirZone(AdvantageAirClimateEntity):
"""AdvantageAir Zone control.""" """AdvantageAir Zone control."""
_attr_hvac_modes = ZONE_HVAC_MODES _attr_hvac_modes = ZONE_HVAC_MODES
_attr_supported_features = SUPPORT_TARGET_TEMPERATURE _attr_supported_features = ClimateEntityFeature.TARGET_TEMPERATURE
def __init__(self, instance, ac_key, zone_key): def __init__(self, instance, ac_key, zone_key):
"""Initialize an AdvantageAir Zone control.""" """Initialize an AdvantageAir Zone control."""
@ -183,8 +178,8 @@ class AdvantageAirZone(AdvantageAirClimateEntity):
def hvac_mode(self): def hvac_mode(self):
"""Return the current state as HVAC mode.""" """Return the current state as HVAC mode."""
if self._zone["state"] == ADVANTAGE_AIR_STATE_OPEN: if self._zone["state"] == ADVANTAGE_AIR_STATE_OPEN:
return HVAC_MODE_HEAT_COOL return HVACMode.HEAT_COOL
return HVAC_MODE_OFF return HVACMode.OFF
@property @property
def current_temperature(self): def current_temperature(self):
@ -198,7 +193,7 @@ class AdvantageAirZone(AdvantageAirClimateEntity):
async def async_set_hvac_mode(self, hvac_mode): async def async_set_hvac_mode(self, hvac_mode):
"""Set the HVAC Mode and State.""" """Set the HVAC Mode and State."""
if hvac_mode == HVAC_MODE_OFF: if hvac_mode == HVACMode.OFF:
await self.async_change( await self.async_change(
{ {
self.ac_key: { self.ac_key: {

View File

@ -1,11 +1,9 @@
"""Cover platform for Advantage Air integration.""" """Cover platform for Advantage Air integration."""
from homeassistant.components.cover import ( from homeassistant.components.cover import (
ATTR_POSITION, ATTR_POSITION,
SUPPORT_CLOSE,
SUPPORT_OPEN,
SUPPORT_SET_POSITION,
CoverDeviceClass, CoverDeviceClass,
CoverEntity, CoverEntity,
CoverEntityFeature,
) )
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
@ -43,7 +41,11 @@ class AdvantageAirZoneVent(AdvantageAirEntity, CoverEntity):
"""Advantage Air Cover Class.""" """Advantage Air Cover Class."""
_attr_device_class = CoverDeviceClass.DAMPER _attr_device_class = CoverDeviceClass.DAMPER
_attr_supported_features = SUPPORT_OPEN | SUPPORT_CLOSE | SUPPORT_SET_POSITION _attr_supported_features = (
CoverEntityFeature.OPEN
| CoverEntityFeature.CLOSE
| CoverEntityFeature.SET_POSITION
)
def __init__(self, instance, ac_key, zone_key): def __init__(self, instance, ac_key, zone_key):
"""Initialize an Advantage Air Cover Class.""" """Initialize an Advantage Air Cover Class."""

View File

@ -14,7 +14,7 @@
"longitude": "Longitud", "longitude": "Longitud",
"name": "Nom de la integraci\u00f3" "name": "Nom de la integraci\u00f3"
}, },
"description": "Configura la integraci\u00f3 d'AEMET OpenData. Per generar la clau API, v\u00e9s a https://opendata.aemet.es/centrodedescargas/altaUsuario", "description": "Per generar la clau API, v\u00e9s a https://opendata.aemet.es/centrodedescargas/altaUsuario",
"title": "AEMET OpenData" "title": "AEMET OpenData"
} }
} }

View File

@ -14,7 +14,7 @@
"longitude": "L\u00e4ngengrad", "longitude": "L\u00e4ngengrad",
"name": "Name der Integration" "name": "Name der Integration"
}, },
"description": "Richte die AEMET OpenData Integration ein. Um den API-Schl\u00fcssel zu generieren, besuche https://opendata.aemet.es/centrodedescargas/altaUsuario", "description": "Um den API-Schl\u00fcssel zu generieren, besuche https://opendata.aemet.es/centrodedescargas/altaUsuario",
"title": "AEMET OpenData" "title": "AEMET OpenData"
} }
} }

View File

@ -14,7 +14,7 @@
"longitude": "Longitude", "longitude": "Longitude",
"name": "Name of the integration" "name": "Name of the integration"
}, },
"description": "Set up AEMET OpenData integration. To generate API key go to https://opendata.aemet.es/centrodedescargas/altaUsuario", "description": "To generate API key go to https://opendata.aemet.es/centrodedescargas/altaUsuario",
"title": "AEMET OpenData" "title": "AEMET OpenData"
} }
} }

View File

@ -14,7 +14,7 @@
"longitude": "Pikkuskraad", "longitude": "Pikkuskraad",
"name": "Sidumise nimi" "name": "Sidumise nimi"
}, },
"description": "Seadista AEMET OpenData sidumine. API v\u00f5tme loomiseks mine aadressile https://opendata.aemet.es/centrodedescargas/altaUsuario", "description": "API-v\u00f5tme loomiseks mine aadressile https://opendata.aemet.es/centrodedescargas/altaUsuario",
"title": "AEMET OpenData" "title": "AEMET OpenData"
} }
} }

View File

@ -14,7 +14,7 @@
"longitude": "Longitude", "longitude": "Longitude",
"name": "Nom de l'int\u00e9gration" "name": "Nom de l'int\u00e9gration"
}, },
"description": "Configurez l'int\u00e9gration AEMET OpenData. Pour g\u00e9n\u00e9rer la cl\u00e9 API, acc\u00e9dez \u00e0 https://opendata.aemet.es/centrodedescargas/altaUsuario", "description": "Pour g\u00e9n\u00e9rer une cl\u00e9 d'API, rendez-vous sur https://opendata.aemet.es/centrodedescargas/altaUsuario",
"title": "AEMET OpenData" "title": "AEMET OpenData"
} }
} }

View File

@ -14,7 +14,7 @@
"longitude": "Hossz\u00fas\u00e1g", "longitude": "Hossz\u00fas\u00e1g",
"name": "Az integr\u00e1ci\u00f3 neve" "name": "Az integr\u00e1ci\u00f3 neve"
}, },
"description": "\u00c1ll\u00edtsa be az AEMET OpenData integr\u00e1ci\u00f3t. Az API-kulcs el\u0151\u00e1ll\u00edt\u00e1s\u00e1hoz keresse fel a https://opendata.aemet.es/centrodedescargas/altaUsuario webhelyet.", "description": "Az API-kulcs l\u00e9trehoz\u00e1s\u00e1hoz keresse fel a https://opendata.aemet.es/centrodedescargas/altaUsuario webhelyet",
"title": "AEMET OpenData" "title": "AEMET OpenData"
} }
} }

View File

@ -14,7 +14,7 @@
"longitude": "Bujur", "longitude": "Bujur",
"name": "Nama integrasi" "name": "Nama integrasi"
}, },
"description": "Siapkan integrasi AEMET OpenData. Untuk menghasilkan kunci API, buka https://opendata.aemet.es/centrodedescargas/altaUsuario", "description": "Untuk membuat kunci API, buka https://opendata.aemet.es/centrodedescargas/altaUsuario",
"title": "AEMET OpenData" "title": "AEMET OpenData"
} }
} }

View File

@ -14,7 +14,7 @@
"longitude": "Logitudine", "longitude": "Logitudine",
"name": "Nome dell'integrazione" "name": "Nome dell'integrazione"
}, },
"description": "Imposta l'integrazione di AEMET OpenData. Per generare la chiave API, vai su https://opendata.aemet.es/centrodedescargas/altaUsuario", "description": "Per generare la chiave API, vai su https://opendata.aemet.es/centrodescargas/altaUsuario",
"title": "AEMET OpenData" "title": "AEMET OpenData"
} }
} }

View File

@ -14,7 +14,7 @@
"longitude": "Lengtegraad", "longitude": "Lengtegraad",
"name": "Naam van de integratie" "name": "Naam van de integratie"
}, },
"description": "Stel AEMET OpenData-integratie in. Ga naar https://opendata.aemet.es/centrodedescargas/altaUsuario om een API-sleutel te genereren", "description": "Om een API sleutel te genereren ga naar https://opendata.aemet.es/centrodedescargas/altaUsuario",
"title": "AEMET OpenData" "title": "AEMET OpenData"
} }
} }

View File

@ -14,7 +14,7 @@
"longitude": "Lengdegrad", "longitude": "Lengdegrad",
"name": "Navnet p\u00e5 integrasjonen" "name": "Navnet p\u00e5 integrasjonen"
}, },
"description": "Sett opp AEMET OpenData-integrasjon. For \u00e5 generere API-n\u00f8kkel, g\u00e5 til https://opendata.aemet.es/centrodedescargas/altaUsuario", "description": "For \u00e5 generere API-n\u00f8kkel, g\u00e5 til https://opendata.aemet.es/centrodedescargas/altaUsuario",
"title": "AEMET OpenData" "title": "AEMET OpenData"
} }
} }

View File

@ -14,7 +14,7 @@
"longitude": "D\u0142ugo\u015b\u0107 geograficzna", "longitude": "D\u0142ugo\u015b\u0107 geograficzna",
"name": "Nazwa integracji" "name": "Nazwa integracji"
}, },
"description": "Skonfiguruj integracj\u0119 AEMET OpenData. Aby wygenerowa\u0107 klucz API, przejd\u017a do https://opendata.aemet.es/centrodedescargas/altaUsuario", "description": "Aby wygenerowa\u0107 klucz API, przejd\u017a do https://opendata.aemet.es/centrodedescargas/altaUsuario",
"title": "AEMET OpenData" "title": "AEMET OpenData"
} }
} }

View File

@ -14,7 +14,7 @@
"longitude": "Longitude", "longitude": "Longitude",
"name": "Nome da integra\u00e7\u00e3o" "name": "Nome da integra\u00e7\u00e3o"
}, },
"description": "Configure a integra\u00e7\u00e3o AEMET OpenData. Para gerar a chave API acesse https://opendata.aemet.es/centrodedescargas/altaUsuario", "description": "Para gerar a chave API acesse https://opendata.aemet.es/centrodedescargas/altaUsuario",
"title": "AEMET OpenData" "title": "AEMET OpenData"
} }
} }

View File

@ -14,7 +14,7 @@
"longitude": "\u0414\u043e\u043b\u0433\u043e\u0442\u0430", "longitude": "\u0414\u043e\u043b\u0433\u043e\u0442\u0430",
"name": "\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435" "name": "\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435"
}, },
"description": "\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 Home Assistant \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438 \u0441 AEMET OpenData. \u0427\u0442\u043e\u0431\u044b \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u044e\u0447 API, \u043f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u043d\u0430 https://opendata.aemet.es/centrodedescargas/altaUsuario.", "description": "\u0427\u0442\u043e\u0431\u044b \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u044e\u0447 API, \u043f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 https://opendata.aemet.es/centrodedescargas/altaUsuario.",
"title": "AEMET OpenData" "title": "AEMET OpenData"
} }
} }

View File

@ -14,7 +14,7 @@
"longitude": "Boylam", "longitude": "Boylam",
"name": "Entegrasyonun ad\u0131" "name": "Entegrasyonun ad\u0131"
}, },
"description": "AEMET OpenData entegrasyonunu ayarlay\u0131n. API anahtar\u0131 olu\u015fturmak i\u00e7in https://opendata.aemet.es/centrodedescargas/altaUsuario adresine gidin.", "description": "API anahtar\u0131 olu\u015fturmak i\u00e7in https://opendata.aemet.es/centrodedescargas/altaUsuario adresine gidin.",
"title": "AEMET OpenData" "title": "AEMET OpenData"
} }
} }

View File

@ -14,7 +14,7 @@
"longitude": "\u7d93\u5ea6", "longitude": "\u7d93\u5ea6",
"name": "\u6574\u5408\u540d\u7a31" "name": "\u6574\u5408\u540d\u7a31"
}, },
"description": "\u6b32\u8a2d\u5b9a AEMET OpenData \u6574\u5408\u3002\u8acb\u81f3 https://opendata.aemet.es/centrodedescargas/altaUsuario \u7522\u751f API \u91d1\u9470", "description": "\u8acb\u81f3 https://opendata.aemet.es/centrodedescargas/altaUsuario \u4ee5\u7522\u751f API \u91d1\u9470",
"title": "AEMET OpenData" "title": "AEMET OpenData"
} }
} }

View File

@ -1,9 +1,7 @@
"""Support for Agent DVR Alarm Control Panels.""" """Support for Agent DVR Alarm Control Panels."""
from homeassistant.components.alarm_control_panel import AlarmControlPanelEntity from homeassistant.components.alarm_control_panel import (
from homeassistant.components.alarm_control_panel.const import ( AlarmControlPanelEntity,
SUPPORT_ALARM_ARM_AWAY, AlarmControlPanelEntityFeature,
SUPPORT_ALARM_ARM_HOME,
SUPPORT_ALARM_ARM_NIGHT,
) )
from homeassistant.const import ( from homeassistant.const import (
STATE_ALARM_ARMED_AWAY, STATE_ALARM_ARMED_AWAY,
@ -38,7 +36,9 @@ class AgentBaseStation(AlarmControlPanelEntity):
_attr_icon = ICON _attr_icon = ICON
_attr_supported_features = ( _attr_supported_features = (
SUPPORT_ALARM_ARM_HOME | SUPPORT_ALARM_ARM_AWAY | SUPPORT_ALARM_ARM_NIGHT AlarmControlPanelEntityFeature.ARM_HOME
| AlarmControlPanelEntityFeature.ARM_AWAY
| AlarmControlPanelEntityFeature.ARM_NIGHT
) )
def __init__(self, client): def __init__(self, client):

View File

@ -4,7 +4,7 @@ import logging
from agent import AgentError from agent import AgentError
from homeassistant.components.camera import SUPPORT_ON_OFF from homeassistant.components.camera import CameraEntityFeature
from homeassistant.components.mjpeg import MjpegCamera, filter_urllib3_logging from homeassistant.components.mjpeg import MjpegCamera, filter_urllib3_logging
from homeassistant.const import ATTR_ATTRIBUTION from homeassistant.const import ATTR_ATTRIBUTION
from homeassistant.helpers import entity_platform from homeassistant.helpers import entity_platform
@ -63,6 +63,8 @@ async def async_setup_entry(
class AgentCamera(MjpegCamera): class AgentCamera(MjpegCamera):
"""Representation of an Agent Device Stream.""" """Representation of an Agent Device Stream."""
_attr_supported_features = CameraEntityFeature.ON_OFF
def __init__(self, device): def __init__(self, device):
"""Initialize as a subclass of MjpegCamera.""" """Initialize as a subclass of MjpegCamera."""
self.device = device self.device = device
@ -134,11 +136,6 @@ class AgentCamera(MjpegCamera):
"""Return True if entity is connected.""" """Return True if entity is connected."""
return self.device.connected return self.device.connected
@property
def supported_features(self) -> int:
"""Return supported features."""
return SUPPORT_ON_OFF
@property @property
def is_on(self) -> bool: def is_on(self) -> bool:
"""Return true if on.""" """Return true if on."""

View File

@ -4,7 +4,7 @@
"already_configured": "Az eszk\u00f6z m\u00e1r konfigur\u00e1lva van" "already_configured": "Az eszk\u00f6z m\u00e1r konfigur\u00e1lva van"
}, },
"error": { "error": {
"already_in_progress": "A konfigur\u00e1l\u00e1s m\u00e1r folyamatban van", "already_in_progress": "A be\u00e1ll\u00edt\u00e1si folyamat m\u00e1r el lett kezdve",
"cannot_connect": "Sikertelen csatlakoz\u00e1s" "cannot_connect": "Sikertelen csatlakoz\u00e1s"
}, },
"step": { "step": {

View File

@ -0,0 +1,31 @@
"""Diagnostics support for Airly."""
from __future__ import annotations
from homeassistant.components.diagnostics import async_redact_data
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import (
CONF_API_KEY,
CONF_LATITUDE,
CONF_LONGITUDE,
CONF_UNIQUE_ID,
)
from homeassistant.core import HomeAssistant
from . import AirlyDataUpdateCoordinator
from .const import DOMAIN
TO_REDACT = {CONF_API_KEY, CONF_LATITUDE, CONF_LONGITUDE, CONF_UNIQUE_ID}
async def async_get_config_entry_diagnostics(
hass: HomeAssistant, config_entry: ConfigEntry
) -> dict:
"""Return diagnostics for a config entry."""
coordinator: AirlyDataUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id]
diagnostics_data = {
"config_entry": async_redact_data(config_entry.as_dict(), TO_REDACT),
"coordinator_data": coordinator.data,
}
return diagnostics_data

View File

@ -15,7 +15,7 @@
"longitude": "Longitud", "longitude": "Longitud",
"name": "Nom" "name": "Nom"
}, },
"description": "Configura la integraci\u00f3 de qualitat de l'aire Airly. Per generar la clau API, v\u00e9s a https://developer.airly.eu/register", "description": "Per generar la clau API, v\u00e9s a https://developer.airly.eu/register",
"title": "Airly" "title": "Airly"
} }
} }

View File

@ -15,7 +15,7 @@
"longitude": "L\u00e4ngengrad", "longitude": "L\u00e4ngengrad",
"name": "Name" "name": "Name"
}, },
"description": "Einrichtung der Airly-Luftqualit\u00e4t Integration. Um einen API-Schl\u00fcssel zu generieren, registriere dich auf https://developer.airly.eu/register", "description": "Um einen API-Schl\u00fcssel zu generieren, besuche https://developer.airly.eu/register",
"title": "Airly" "title": "Airly"
} }
} }

View File

@ -15,7 +15,7 @@
"longitude": "Longitude", "longitude": "Longitude",
"name": "Name" "name": "Name"
}, },
"description": "Set up Airly air quality integration. To generate API key go to https://developer.airly.eu/register", "description": "To generate API key go to https://developer.airly.eu/register",
"title": "Airly" "title": "Airly"
} }
} }

View File

@ -15,7 +15,7 @@
"longitude": "Pikkuskraad", "longitude": "Pikkuskraad",
"name": "Nimi" "name": "Nimi"
}, },
"description": "Seadista Airly \u00f5hukvaliteedi andmete sidumine. API v\u00f5tme loomiseks mine aadressile https://developer.airly.eu/register", "description": "API-v\u00f5tme loomiseks mine aadressile https://developer.airly.eu/register",
"title": "" "title": ""
} }
} }

View File

@ -15,7 +15,7 @@
"longitude": "Longitude", "longitude": "Longitude",
"name": "Nom" "name": "Nom"
}, },
"description": "Configurez l'int\u00e9gration de la qualit\u00e9 de l'air Airly. Pour g\u00e9n\u00e9rer une cl\u00e9 API, rendez-vous sur https://developer.airly.eu/register.", "description": "Pour g\u00e9n\u00e9rer une cl\u00e9 d'API, rendez-vous sur https://developer.airly.eu/register",
"title": "Airly" "title": "Airly"
} }
} }

View File

@ -13,9 +13,9 @@
"api_key": "API kulcs", "api_key": "API kulcs",
"latitude": "Sz\u00e9less\u00e9g", "latitude": "Sz\u00e9less\u00e9g",
"longitude": "Hossz\u00fas\u00e1g", "longitude": "Hossz\u00fas\u00e1g",
"name": "N\u00e9v" "name": "Elnevez\u00e9s"
}, },
"description": "Az Airly leveg\u0151min\u0151s\u00e9gi integr\u00e1ci\u00f3j\u00e1nak be\u00e1ll\u00edt\u00e1sa. Api-kulcs l\u00e9trehoz\u00e1s\u00e1hoz nyissa meg a k\u00f6vetkez\u0151 weboldalt: https://developer.airly.eu/register", "description": "Az API-kulcs l\u00e9trehoz\u00e1s\u00e1hoz keresse fel a https://developer.airly.eu/register webhelyet",
"title": "Airly" "title": "Airly"
} }
} }

View File

@ -15,7 +15,7 @@
"longitude": "Bujur", "longitude": "Bujur",
"name": "Nama" "name": "Nama"
}, },
"description": "Siapkan integrasi kualitas udara Airly. Untuk membuat kunci API, buka https://developer.airly.eu/register", "description": "Untuk membuat kunci API, buka https://developer.airly.eu/register",
"title": "Airly" "title": "Airly"
} }
} }

View File

@ -15,7 +15,7 @@
"longitude": "Logitudine", "longitude": "Logitudine",
"name": "Nome" "name": "Nome"
}, },
"description": "Configurazione dell'integrazione della qualit\u00e0 dell'aria Airly. Per generare la chiave API vai su https://developer.airly.eu/register", "description": "Per generare la chiave API, vai su https://developer.airly.eu/register",
"title": "Airly" "title": "Airly"
} }
} }

View File

@ -15,7 +15,7 @@
"longitude": "Lengtegraad", "longitude": "Lengtegraad",
"name": "Naam" "name": "Naam"
}, },
"description": "Airly-integratie van luchtkwaliteit instellen. Ga naar https://developer.airly.eu/register om de API-sleutel te genereren", "description": "Om een API sleutel te genereren ga naar https://developer.airly.eu/register",
"title": "Airly" "title": "Airly"
} }
} }

View File

@ -15,7 +15,7 @@
"longitude": "Lengdegrad", "longitude": "Lengdegrad",
"name": "Navn" "name": "Navn"
}, },
"description": "Sett opp Airly luftkvalitet integrasjon. For \u00e5 opprette API-n\u00f8kkel, g\u00e5 til [https://developer.airly.eu/register](https://developer.airly.eu/register)", "description": "For \u00e5 generere API-n\u00f8kkel, g\u00e5 til https://developer.airly.eu/register",
"title": "" "title": ""
} }
} }

View File

@ -15,7 +15,7 @@
"longitude": "D\u0142ugo\u015b\u0107 geograficzna", "longitude": "D\u0142ugo\u015b\u0107 geograficzna",
"name": "Nazwa" "name": "Nazwa"
}, },
"description": "Konfiguracja integracji Airly. By wygenerowa\u0107 klucz API, przejd\u017a na stron\u0119 https://developer.airly.eu/register", "description": "By wygenerowa\u0107 klucz API, przejd\u017a na stron\u0119 https://developer.airly.eu/register",
"title": "Airly" "title": "Airly"
} }
} }

View File

@ -15,7 +15,7 @@
"longitude": "Longitude", "longitude": "Longitude",
"name": "Nome" "name": "Nome"
}, },
"description": "Configure a integra\u00e7\u00e3o da qualidade do ar airly. Para gerar a chave de API v\u00e1 para https://developer.airly.eu/register", "description": "Para gerar a chave de API, acesse https://developer.airly.eu/register",
"title": "Airly" "title": "Airly"
} }
} }

View File

@ -15,7 +15,7 @@
"longitude": "\u0414\u043e\u043b\u0433\u043e\u0442\u0430", "longitude": "\u0414\u043e\u043b\u0433\u043e\u0442\u0430",
"name": "\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435" "name": "\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435"
}, },
"description": "\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u043f\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0443 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0430 \u0432\u043e\u0437\u0434\u0443\u0445\u0430 Airly. \u0427\u0442\u043e\u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043b\u044e\u0447 API, \u043f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 https://developer.airly.eu/register.", "description": "\u0427\u0442\u043e\u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043b\u044e\u0447 API, \u043f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 https://developer.airly.eu/register.",
"title": "Airly" "title": "Airly"
} }
} }

View File

@ -15,7 +15,7 @@
"longitude": "Boylam", "longitude": "Boylam",
"name": "Ad" "name": "Ad"
}, },
"description": "Airly hava kalitesi entegrasyonunu ayarlay\u0131n. API anahtar\u0131 olu\u015fturmak i\u00e7in https://developer.airly.eu/register adresine gidin.", "description": "API anahtar\u0131 olu\u015fturmak i\u00e7in https://developer.airly.eu/register adresine gidin.",
"title": "Airly" "title": "Airly"
} }
} }

View File

@ -15,7 +15,7 @@
"longitude": "\u7d93\u5ea6", "longitude": "\u7d93\u5ea6",
"name": "\u540d\u7a31" "name": "\u540d\u7a31"
}, },
"description": "\u6b32\u8a2d\u5b9a Airly \u7a7a\u6c23\u54c1\u8cea\u6574\u5408\u3002\u8acb\u81f3 https://developer.airly.eu/register \u7522\u751f API \u91d1\u9470", "description": "\u8acb\u81f3 https://developer.airly.eu/register \u4ee5\u7522\u751f API \u91d1\u9470",
"title": "Airly" "title": "Airly"
} }
} }

View File

@ -17,7 +17,7 @@
"longitude": "Longitud", "longitude": "Longitud",
"radius": "Radi de l'estaci\u00f3 (milles; opcional)" "radius": "Radi de l'estaci\u00f3 (milles; opcional)"
}, },
"description": "Configura la integraci\u00f3 de qualitat d'aire AirNow. Per generar la clau API, v\u00e9s a https://docs.airnowapi.org/account/request/", "description": "Per generar la clau API, v\u00e9s a https://docs.airnowapi.org/account/request/",
"title": "AirNow" "title": "AirNow"
} }
} }

View File

@ -17,7 +17,7 @@
"longitude": "L\u00e4ngengrad", "longitude": "L\u00e4ngengrad",
"radius": "Stationsradius (Meilen; optional)" "radius": "Stationsradius (Meilen; optional)"
}, },
"description": "Richte die AirNow-Luftqualit\u00e4tsintegration ein. Um den API-Schl\u00fcssel zu generieren, besuche https://docs.airnowapi.org/account/request/.", "description": "Um den API-Schl\u00fcssel zu generieren, besuche https://docs.airnowapi.org/account/request/",
"title": "AirNow" "title": "AirNow"
} }
} }

View File

@ -17,7 +17,7 @@
"longitude": "Longitude", "longitude": "Longitude",
"radius": "Station Radius (miles; optional)" "radius": "Station Radius (miles; optional)"
}, },
"description": "Set up AirNow air quality integration. To generate API key go to https://docs.airnowapi.org/account/request/", "description": "To generate API key go to https://docs.airnowapi.org/account/request/",
"title": "AirNow" "title": "AirNow"
} }
} }

View File

@ -17,7 +17,7 @@
"longitude": "Pikkuskraad", "longitude": "Pikkuskraad",
"radius": "Jaama raadius (miilid; valikuline)" "radius": "Jaama raadius (miilid; valikuline)"
}, },
"description": "Seadista AirNow \u00f5hukvaliteedi sidumine. API-v\u00f5tme loomiseks mine aadressile https://docs.airnowapi.org/account/request/", "description": "API-v\u00f5tme loomiseks mine aadressile https://docs.airnowapi.org/account/request/",
"title": "" "title": ""
} }
} }

View File

@ -17,7 +17,7 @@
"longitude": "Longitude", "longitude": "Longitude",
"radius": "Rayon d'action de la station (en miles, facultatif)" "radius": "Rayon d'action de la station (en miles, facultatif)"
}, },
"description": "Configurez l'int\u00e9gration de la qualit\u00e9 de l'air AirNow. Pour g\u00e9n\u00e9rer la cl\u00e9 API, acc\u00e9dez \u00e0 https://docs.airnowapi.org/account/request/", "description": "Pour g\u00e9n\u00e9rer une cl\u00e9 d'API, rendez-vous sur https://docs.airnowapi.org/account/request/",
"title": "AirNow" "title": "AirNow"
} }
} }

View File

@ -17,7 +17,7 @@
"longitude": "Hossz\u00fas\u00e1g", "longitude": "Hossz\u00fas\u00e1g",
"radius": "\u00c1llom\u00e1s sugara (m\u00e9rf\u00f6ld; opcion\u00e1lis)" "radius": "\u00c1llom\u00e1s sugara (m\u00e9rf\u00f6ld; opcion\u00e1lis)"
}, },
"description": "\u00c1ll\u00edtsa be az AirNow leveg\u0151min\u0151s\u00e9gi integr\u00e1ci\u00f3t. Az API-kulcs el\u0151\u00e1ll\u00edt\u00e1s\u00e1hoz keresse fel a https://docs.airnowapi.org/account/request/ oldalt.", "description": "Az API-kulcs l\u00e9trehoz\u00e1s\u00e1hoz keresse fel a https://docs.airnowapi.org/account/request/ webhelyet",
"title": "AirNow" "title": "AirNow"
} }
} }

View File

@ -17,7 +17,7 @@
"longitude": "Bujur", "longitude": "Bujur",
"radius": "Radius Stasiun (mil; opsional)" "radius": "Radius Stasiun (mil; opsional)"
}, },
"description": "Siapkan integrasi kualitas udara AirNow. Untuk membuat kunci API buka https://docs.airnowapi.org/account/request/", "description": "Untuk membuat kunci API buka https://docs.airnowapi.org/account/request/",
"title": "AirNow" "title": "AirNow"
} }
} }

View File

@ -17,7 +17,7 @@
"longitude": "Logitudine", "longitude": "Logitudine",
"radius": "Raggio stazione (miglia; opzionale)" "radius": "Raggio stazione (miglia; opzionale)"
}, },
"description": "Configura l'integrazione per la qualit\u00e0 dell'aria AirNow. Per generare la chiave API, vai su https://docs.airnowapi.org/account/request/", "description": "Per generare la chiave API vai su https://docs.airnowapi.org/account/request/",
"title": "AirNow" "title": "AirNow"
} }
} }

View File

@ -17,7 +17,7 @@
"longitude": "Lengtegraad", "longitude": "Lengtegraad",
"radius": "Stationsradius (mijl; optioneel)" "radius": "Stationsradius (mijl; optioneel)"
}, },
"description": "AirNow luchtkwaliteit integratie opzetten. Om een API sleutel te genereren ga naar https://docs.airnowapi.org/account/request/", "description": "Om een API sleutel te genereren ga naar https://docs.airnowapi.org/account/request/",
"title": "AirNow" "title": "AirNow"
} }
} }

View File

@ -17,7 +17,7 @@
"longitude": "Lengdegrad", "longitude": "Lengdegrad",
"radius": "Stasjonsradius (miles; valgfritt)" "radius": "Stasjonsradius (miles; valgfritt)"
}, },
"description": "Konfigurer integrering av luftkvalitet i AirNow. For \u00e5 generere en API-n\u00f8kkel, g\u00e5r du til https://docs.airnowapi.org/account/request/", "description": "For \u00e5 generere API-n\u00f8kkel, g\u00e5 til https://docs.airnowapi.org/account/request/",
"title": "" "title": ""
} }
} }

View File

@ -17,7 +17,7 @@
"longitude": "D\u0142ugo\u015b\u0107 geograficzna", "longitude": "D\u0142ugo\u015b\u0107 geograficzna",
"radius": "Promie\u0144 od stacji (w milach; opcjonalnie)" "radius": "Promie\u0144 od stacji (w milach; opcjonalnie)"
}, },
"description": "Konfiguracja integracji jako\u015bci powietrza AirNow. Aby wygenerowa\u0107 klucz API, przejd\u017a do https://docs.airnowapi.org/account/request/", "description": "Aby wygenerowa\u0107 klucz API, przejd\u017a do https://docs.airnowapi.org/account/request/",
"title": "AirNow" "title": "AirNow"
} }
} }

View File

@ -17,7 +17,7 @@
"longitude": "Longitude", "longitude": "Longitude",
"radius": "Raio da Esta\u00e7\u00e3o (milhas; opcional)" "radius": "Raio da Esta\u00e7\u00e3o (milhas; opcional)"
}, },
"description": "Configure a integra\u00e7\u00e3o da qualidade do ar AirNow. Para gerar a chave de API, acesse https://docs.airnowapi.org/account/request/", "description": "Para gerar a chave de API, acesse https://docs.airnowapi.org/account/request/",
"title": "AirNow" "title": "AirNow"
} }
} }

View File

@ -17,7 +17,7 @@
"longitude": "\u0414\u043e\u043b\u0433\u043e\u0442\u0430", "longitude": "\u0414\u043e\u043b\u0433\u043e\u0442\u0430",
"radius": "\u0420\u0430\u0434\u0438\u0443\u0441 \u0441\u0442\u0430\u043d\u0446\u0438\u0438 (\u0432 \u043c\u0438\u043b\u044f\u0445; \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e)" "radius": "\u0420\u0430\u0434\u0438\u0443\u0441 \u0441\u0442\u0430\u043d\u0446\u0438\u0438 (\u0432 \u043c\u0438\u043b\u044f\u0445; \u043d\u0435\u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e)"
}, },
"description": "\u0418\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u044f \u0441\u0435\u0440\u0432\u0438\u0441\u0430 \u043f\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0443 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0430 \u0432\u043e\u0437\u0434\u0443\u0445\u0430 AirNow. \u0427\u0442\u043e\u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043b\u044e\u0447 API, \u043f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 https://docs.airnowapi.org/account/request/.", "description": "\u0427\u0442\u043e\u0431\u044b \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043b\u044e\u0447 API, \u043f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u043f\u043e \u0441\u0441\u044b\u043b\u043a\u0435 https://docs.airnowapi.org/account/request/.",
"title": "AirNow" "title": "AirNow"
} }
} }

View File

@ -17,7 +17,7 @@
"longitude": "Boylam", "longitude": "Boylam",
"radius": "\u0130stasyon Yar\u0131\u00e7ap\u0131 (mil; iste\u011fe ba\u011fl\u0131)" "radius": "\u0130stasyon Yar\u0131\u00e7ap\u0131 (mil; iste\u011fe ba\u011fl\u0131)"
}, },
"description": "AirNow hava kalitesi entegrasyonunu ayarlay\u0131n. API anahtar\u0131 olu\u015fturmak i\u00e7in https://docs.airnowapi.org/account/request/ adresine gidin.", "description": "API anahtar\u0131 olu\u015fturmak i\u00e7in https://docs.airnowapi.org/account/request/ adresine gidin.",
"title": "AirNow" "title": "AirNow"
} }
} }

View File

@ -17,7 +17,7 @@
"longitude": "\u7d93\u5ea6", "longitude": "\u7d93\u5ea6",
"radius": "\u89c0\u6e2c\u7ad9\u534a\u5f91\uff08\u82f1\u91cc\uff1b\u9078\u9805\uff09" "radius": "\u89c0\u6e2c\u7ad9\u534a\u5f91\uff08\u82f1\u91cc\uff1b\u9078\u9805\uff09"
}, },
"description": "\u6b32\u8a2d\u5b9a AirNow \u7a7a\u6c23\u54c1\u8cea\u6574\u5408\u3002\u8acb\u81f3 https://docs.airnowapi.org/account/request/ \u7522\u751f API \u91d1\u9470", "description": "\u8acb\u81f3 https://docs.airnowapi.org/account/request/ \u4ee5\u7522\u751f API \u91d1\u9470",
"title": "AirNow" "title": "AirNow"
} }
} }

View File

@ -11,14 +11,8 @@ from homeassistant.components.climate.const import (
FAN_HIGH, FAN_HIGH,
FAN_LOW, FAN_LOW,
FAN_MEDIUM, FAN_MEDIUM,
HVAC_MODE_AUTO, ClimateEntityFeature,
HVAC_MODE_COOL, HVACMode,
HVAC_MODE_DRY,
HVAC_MODE_FAN_ONLY,
HVAC_MODE_HEAT,
HVAC_MODE_OFF,
SUPPORT_FAN_MODE,
SUPPORT_TARGET_TEMPERATURE,
) )
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS
@ -29,24 +23,23 @@ from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN from .const import DOMAIN
SUPPORT_FLAGS = SUPPORT_TARGET_TEMPERATURE | SUPPORT_FAN_MODE
AT_TO_HA_STATE = { AT_TO_HA_STATE = {
"Heat": HVAC_MODE_HEAT, "Heat": HVACMode.HEAT,
"Cool": HVAC_MODE_COOL, "Cool": HVACMode.COOL,
"AutoHeat": HVAC_MODE_AUTO, # airtouch reports either autoheat or autocool "AutoHeat": HVACMode.AUTO, # airtouch reports either autoheat or autocool
"AutoCool": HVAC_MODE_AUTO, "AutoCool": HVACMode.AUTO,
"Auto": HVAC_MODE_AUTO, "Auto": HVACMode.AUTO,
"Dry": HVAC_MODE_DRY, "Dry": HVACMode.DRY,
"Fan": HVAC_MODE_FAN_ONLY, "Fan": HVACMode.FAN_ONLY,
} }
HA_STATE_TO_AT = { HA_STATE_TO_AT = {
HVAC_MODE_HEAT: "Heat", HVACMode.HEAT: "Heat",
HVAC_MODE_COOL: "Cool", HVACMode.COOL: "Cool",
HVAC_MODE_AUTO: "Auto", HVACMode.AUTO: "Auto",
HVAC_MODE_DRY: "Dry", HVACMode.DRY: "Dry",
HVAC_MODE_FAN_ONLY: "Fan", HVACMode.FAN_ONLY: "Fan",
HVAC_MODE_OFF: "Off", HVACMode.OFF: "Off",
} }
AT_TO_HA_FAN_SPEED = { AT_TO_HA_FAN_SPEED = {
@ -59,7 +52,7 @@ AT_TO_HA_FAN_SPEED = {
"Turbo": "turbo", "Turbo": "turbo",
} }
AT_GROUP_MODES = [HVAC_MODE_OFF, HVAC_MODE_FAN_ONLY] AT_GROUP_MODES = [HVACMode.OFF, HVACMode.FAN_ONLY]
HA_FAN_SPEED_TO_AT = {value: key for key, value in AT_TO_HA_FAN_SPEED.items()} HA_FAN_SPEED_TO_AT = {value: key for key, value in AT_TO_HA_FAN_SPEED.items()}
@ -90,7 +83,9 @@ async def async_setup_entry(
class AirtouchAC(CoordinatorEntity, ClimateEntity): class AirtouchAC(CoordinatorEntity, ClimateEntity):
"""Representation of an AirTouch 4 ac.""" """Representation of an AirTouch 4 ac."""
_attr_supported_features = SUPPORT_TARGET_TEMPERATURE | SUPPORT_FAN_MODE _attr_supported_features = (
ClimateEntityFeature.TARGET_TEMPERATURE | ClimateEntityFeature.FAN_MODE
)
_attr_temperature_unit = TEMP_CELSIUS _attr_temperature_unit = TEMP_CELSIUS
def __init__(self, coordinator, ac_number, info): def __init__(self, coordinator, ac_number, info):
@ -147,7 +142,7 @@ class AirtouchAC(CoordinatorEntity, ClimateEntity):
"""Return hvac target hvac state.""" """Return hvac target hvac state."""
is_off = self._unit.PowerState == "Off" is_off = self._unit.PowerState == "Off"
if is_off: if is_off:
return HVAC_MODE_OFF return HVACMode.OFF
return AT_TO_HA_STATE[self._airtouch.acs[self._ac_number].AcMode] return AT_TO_HA_STATE[self._airtouch.acs[self._ac_number].AcMode]
@ -156,7 +151,7 @@ class AirtouchAC(CoordinatorEntity, ClimateEntity):
"""Return the list of available operation modes.""" """Return the list of available operation modes."""
airtouch_modes = self._airtouch.GetSupportedCoolingModesForAc(self._ac_number) airtouch_modes = self._airtouch.GetSupportedCoolingModesForAc(self._ac_number)
modes = [AT_TO_HA_STATE[mode] for mode in airtouch_modes] modes = [AT_TO_HA_STATE[mode] for mode in airtouch_modes]
modes.append(HVAC_MODE_OFF) modes.append(HVACMode.OFF)
return modes return modes
async def async_set_hvac_mode(self, hvac_mode): async def async_set_hvac_mode(self, hvac_mode):
@ -164,7 +159,7 @@ class AirtouchAC(CoordinatorEntity, ClimateEntity):
if hvac_mode not in HA_STATE_TO_AT: if hvac_mode not in HA_STATE_TO_AT:
raise ValueError(f"Unsupported HVAC mode: {hvac_mode}") raise ValueError(f"Unsupported HVAC mode: {hvac_mode}")
if hvac_mode == HVAC_MODE_OFF: if hvac_mode == HVACMode.OFF:
return await self.async_turn_off() return await self.async_turn_off()
await self._airtouch.SetCoolingModeForAc( await self._airtouch.SetCoolingModeForAc(
self._ac_number, HA_STATE_TO_AT[hvac_mode] self._ac_number, HA_STATE_TO_AT[hvac_mode]
@ -204,7 +199,7 @@ class AirtouchAC(CoordinatorEntity, ClimateEntity):
class AirtouchGroup(CoordinatorEntity, ClimateEntity): class AirtouchGroup(CoordinatorEntity, ClimateEntity):
"""Representation of an AirTouch 4 group.""" """Representation of an AirTouch 4 group."""
_attr_supported_features = SUPPORT_TARGET_TEMPERATURE _attr_supported_features = ClimateEntityFeature.TARGET_TEMPERATURE
_attr_temperature_unit = TEMP_CELSIUS _attr_temperature_unit = TEMP_CELSIUS
_attr_hvac_modes = AT_GROUP_MODES _attr_hvac_modes = AT_GROUP_MODES
@ -267,18 +262,18 @@ class AirtouchGroup(CoordinatorEntity, ClimateEntity):
# there are other power states that aren't 'on' but still count as on (eg. 'Turbo') # there are other power states that aren't 'on' but still count as on (eg. 'Turbo')
is_off = self._unit.PowerState == "Off" is_off = self._unit.PowerState == "Off"
if is_off: if is_off:
return HVAC_MODE_OFF return HVACMode.OFF
return HVAC_MODE_FAN_ONLY return HVACMode.FAN_ONLY
async def async_set_hvac_mode(self, hvac_mode): async def async_set_hvac_mode(self, hvac_mode):
"""Set new operation mode.""" """Set new operation mode."""
if hvac_mode not in HA_STATE_TO_AT: if hvac_mode not in HA_STATE_TO_AT:
raise ValueError(f"Unsupported HVAC mode: {hvac_mode}") raise ValueError(f"Unsupported HVAC mode: {hvac_mode}")
if hvac_mode == HVAC_MODE_OFF: if hvac_mode == HVACMode.OFF:
return await self.async_turn_off() return await self.async_turn_off()
if self.hvac_mode == HVAC_MODE_OFF: if self.hvac_mode == HVACMode.OFF:
await self.async_turn_on() await self.async_turn_on()
self._unit = self._airtouch.GetGroups()[self._group_number] self._unit = self._airtouch.GetGroups()[self._group_number]
_LOGGER.debug( _LOGGER.debug(

View File

@ -10,7 +10,7 @@
}, },
"airvisual__pollutant_level": { "airvisual__pollutant_level": {
"good": "Bon", "good": "Bon",
"hazardous": "Hasardeux", "hazardous": "Dangereux",
"moderate": "Mod\u00e9r\u00e9", "moderate": "Mod\u00e9r\u00e9",
"unhealthy": "Malsain", "unhealthy": "Malsain",
"unhealthy_sensitive": "Malsain pour les groupes sensibles", "unhealthy_sensitive": "Malsain pour les groupes sensibles",

View File

@ -1,23 +1,30 @@
"""The Airzone integration.""" """The Airzone integration."""
from __future__ import annotations from __future__ import annotations
import logging
from typing import Any from typing import Any
from aioairzone.common import ConnectionOptions
from aioairzone.const import ( from aioairzone.const import (
AZD_ID, AZD_ID,
AZD_MAC,
AZD_NAME, AZD_NAME,
AZD_SYSTEM, AZD_SYSTEM,
AZD_THERMOSTAT_FW, AZD_THERMOSTAT_FW,
AZD_THERMOSTAT_MODEL, AZD_THERMOSTAT_MODEL,
AZD_WEBSERVER,
AZD_ZONES, AZD_ZONES,
DEFAULT_SYSTEM_ID,
) )
from aioairzone.localapi import AirzoneLocalApi from aioairzone.localapi import AirzoneLocalApi, ConnectionOptions
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import CONF_HOST, CONF_PORT, Platform from homeassistant.const import CONF_HOST, CONF_ID, CONF_PORT, Platform
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers import aiohttp_client from homeassistant.helpers import (
aiohttp_client,
device_registry as dr,
entity_registry as er,
)
from homeassistant.helpers.entity import DeviceInfo from homeassistant.helpers.entity import DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.helpers.update_coordinator import CoordinatorEntity
@ -26,10 +33,20 @@ from .coordinator import AirzoneUpdateCoordinator
PLATFORMS: list[Platform] = [Platform.BINARY_SENSOR, Platform.CLIMATE, Platform.SENSOR] PLATFORMS: list[Platform] = [Platform.BINARY_SENSOR, Platform.CLIMATE, Platform.SENSOR]
_LOGGER = logging.getLogger(__name__)
class AirzoneEntity(CoordinatorEntity[AirzoneUpdateCoordinator]): class AirzoneEntity(CoordinatorEntity[AirzoneUpdateCoordinator]):
"""Define an Airzone entity.""" """Define an Airzone entity."""
def get_airzone_value(self, key) -> Any:
"""Return Airzone entity value by key."""
raise NotImplementedError()
class AirzoneZoneEntity(AirzoneEntity):
"""Define an Airzone Zone entity."""
def __init__( def __init__(
self, self,
coordinator: AirzoneUpdateCoordinator, coordinator: AirzoneUpdateCoordinator,
@ -47,12 +64,15 @@ class AirzoneEntity(CoordinatorEntity[AirzoneUpdateCoordinator]):
self._attr_device_info: DeviceInfo = { self._attr_device_info: DeviceInfo = {
"identifiers": {(DOMAIN, f"{entry.entry_id}_{system_zone_id}")}, "identifiers": {(DOMAIN, f"{entry.entry_id}_{system_zone_id}")},
"manufacturer": MANUFACTURER, "manufacturer": MANUFACTURER,
"model": self.get_zone_value(AZD_THERMOSTAT_MODEL), "model": self.get_airzone_value(AZD_THERMOSTAT_MODEL),
"name": f"Airzone [{system_zone_id}] {zone_data[AZD_NAME]}", "name": f"Airzone [{system_zone_id}] {zone_data[AZD_NAME]}",
"sw_version": self.get_zone_value(AZD_THERMOSTAT_FW), "sw_version": self.get_airzone_value(AZD_THERMOSTAT_FW),
} }
self._attr_unique_id = (
entry.entry_id if entry.unique_id is None else entry.unique_id
)
def get_zone_value(self, key): def get_airzone_value(self, key) -> Any:
"""Return zone value by key.""" """Return zone value by key."""
value = None value = None
if self.system_zone_id in self.coordinator.data[AZD_ZONES]: if self.system_zone_id in self.coordinator.data[AZD_ZONES]:
@ -62,17 +82,58 @@ class AirzoneEntity(CoordinatorEntity[AirzoneUpdateCoordinator]):
return value return value
async def _async_migrate_unique_ids(
hass: HomeAssistant,
entry: ConfigEntry,
coordinator: AirzoneUpdateCoordinator,
) -> None:
"""Migrate entities when the mac address gets discovered."""
@callback
def _async_migrator(entity_entry: er.RegistryEntry) -> dict[str, Any] | None:
updates = None
unique_id = entry.unique_id
entry_id = entry.entry_id
entity_unique_id = entity_entry.unique_id
if entity_unique_id.startswith(entry_id):
new_unique_id = f"{unique_id}{entity_unique_id[len(entry_id):]}"
_LOGGER.info(
"Migrating unique_id from [%s] to [%s]",
entity_unique_id,
new_unique_id,
)
updates = {"new_unique_id": new_unique_id}
return updates
if (
entry.unique_id is None
and AZD_WEBSERVER in coordinator.data
and AZD_MAC in coordinator.data[AZD_WEBSERVER]
and (mac := coordinator.data[AZD_WEBSERVER][AZD_MAC]) is not None
):
updates: dict[str, Any] = {
"unique_id": dr.format_mac(mac),
}
hass.config_entries.async_update_entry(entry, **updates)
await er.async_migrate_entries(hass, entry.entry_id, _async_migrator)
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
"""Set up Airzone from a config entry.""" """Set up Airzone from a config entry."""
options = ConnectionOptions( options = ConnectionOptions(
entry.data[CONF_HOST], entry.data[CONF_HOST],
entry.data[CONF_PORT], entry.data[CONF_PORT],
entry.data.get(CONF_ID, DEFAULT_SYSTEM_ID),
) )
airzone = AirzoneLocalApi(aiohttp_client.async_get_clientsession(hass), options) airzone = AirzoneLocalApi(aiohttp_client.async_get_clientsession(hass), options)
coordinator = AirzoneUpdateCoordinator(hass, airzone) coordinator = AirzoneUpdateCoordinator(hass, airzone)
await coordinator.async_config_entry_first_refresh() await coordinator.async_config_entry_first_refresh()
await _async_migrate_unique_ids(hass, entry, coordinator)
hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator hass.data.setdefault(DOMAIN, {})[entry.entry_id] = coordinator

View File

@ -7,6 +7,7 @@ from typing import Any, Final
from aioairzone.const import ( from aioairzone.const import (
AZD_AIR_DEMAND, AZD_AIR_DEMAND,
AZD_BATTERY_LOW,
AZD_ERRORS, AZD_ERRORS,
AZD_FLOOR_DEMAND, AZD_FLOOR_DEMAND,
AZD_NAME, AZD_NAME,
@ -15,8 +16,7 @@ from aioairzone.const import (
) )
from homeassistant.components.binary_sensor import ( from homeassistant.components.binary_sensor import (
DEVICE_CLASS_PROBLEM, BinarySensorDeviceClass,
DEVICE_CLASS_RUNNING,
BinarySensorEntity, BinarySensorEntity,
BinarySensorEntityDescription, BinarySensorEntityDescription,
) )
@ -25,7 +25,7 @@ from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import EntityCategory from homeassistant.helpers.entity import EntityCategory
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AirzoneEntity from . import AirzoneEntity, AirzoneZoneEntity
from .const import DOMAIN from .const import DOMAIN
from .coordinator import AirzoneUpdateCoordinator from .coordinator import AirzoneUpdateCoordinator
@ -37,14 +37,19 @@ class AirzoneBinarySensorEntityDescription(BinarySensorEntityDescription):
attributes: dict[str, str] | None = None attributes: dict[str, str] | None = None
BINARY_SENSOR_TYPES: Final[tuple[AirzoneBinarySensorEntityDescription, ...]] = ( ZONE_BINARY_SENSOR_TYPES: Final[tuple[AirzoneBinarySensorEntityDescription, ...]] = (
AirzoneBinarySensorEntityDescription( AirzoneBinarySensorEntityDescription(
device_class=DEVICE_CLASS_RUNNING, device_class=BinarySensorDeviceClass.RUNNING,
key=AZD_AIR_DEMAND, key=AZD_AIR_DEMAND,
name="Air Demand", name="Air Demand",
), ),
AirzoneBinarySensorEntityDescription( AirzoneBinarySensorEntityDescription(
device_class=DEVICE_CLASS_RUNNING, device_class=BinarySensorDeviceClass.BATTERY,
key=AZD_BATTERY_LOW,
name="Battery Low",
),
AirzoneBinarySensorEntityDescription(
device_class=BinarySensorDeviceClass.RUNNING,
key=AZD_FLOOR_DEMAND, key=AZD_FLOOR_DEMAND,
name="Floor Demand", name="Floor Demand",
), ),
@ -52,7 +57,7 @@ BINARY_SENSOR_TYPES: Final[tuple[AirzoneBinarySensorEntityDescription, ...]] = (
attributes={ attributes={
"errors": AZD_ERRORS, "errors": AZD_ERRORS,
}, },
device_class=DEVICE_CLASS_PROBLEM, device_class=BinarySensorDeviceClass.PROBLEM,
entity_category=EntityCategory.DIAGNOSTIC, entity_category=EntityCategory.DIAGNOSTIC,
key=AZD_PROBLEMS, key=AZD_PROBLEMS,
name="Problem", name="Problem",
@ -66,12 +71,12 @@ async def async_setup_entry(
"""Add Airzone binary sensors from a config_entry.""" """Add Airzone binary sensors from a config_entry."""
coordinator = hass.data[DOMAIN][entry.entry_id] coordinator = hass.data[DOMAIN][entry.entry_id]
binary_sensors = [] binary_sensors: list[AirzoneBinarySensor] = []
for system_zone_id, zone_data in coordinator.data[AZD_ZONES].items(): for system_zone_id, zone_data in coordinator.data[AZD_ZONES].items():
for description in BINARY_SENSOR_TYPES: for description in ZONE_BINARY_SENSOR_TYPES:
if description.key in zone_data: if description.key in zone_data:
binary_sensors.append( binary_sensors.append(
AirzoneBinarySensor( AirzoneZoneBinarySensor(
coordinator, coordinator,
description, description,
entry, entry,
@ -84,7 +89,28 @@ async def async_setup_entry(
class AirzoneBinarySensor(AirzoneEntity, BinarySensorEntity): class AirzoneBinarySensor(AirzoneEntity, BinarySensorEntity):
"""Define an Airzone sensor.""" """Define an Airzone binary sensor."""
entity_description: AirzoneBinarySensorEntityDescription
@property
def extra_state_attributes(self) -> Mapping[str, Any] | None:
"""Return state attributes."""
if not self.entity_description.attributes:
return None
return {
key: self.get_airzone_value(val)
for key, val in self.entity_description.attributes.items()
}
@property
def is_on(self) -> bool | None:
"""Return true if the binary sensor is on."""
return self.get_airzone_value(self.entity_description.key)
class AirzoneZoneBinarySensor(AirzoneZoneEntity, AirzoneBinarySensor):
"""Define an Airzone Zone binary sensor."""
def __init__( def __init__(
self, self,
@ -96,19 +122,9 @@ class AirzoneBinarySensor(AirzoneEntity, BinarySensorEntity):
) -> None: ) -> None:
"""Initialize.""" """Initialize."""
super().__init__(coordinator, entry, system_zone_id, zone_data) super().__init__(coordinator, entry, system_zone_id, zone_data)
self._attr_name = f"{zone_data[AZD_NAME]} {description.name}" self._attr_name = f"{zone_data[AZD_NAME]} {description.name}"
self._attr_unique_id = f"{entry.entry_id}_{system_zone_id}_{description.key}" self._attr_unique_id = (
self.attributes = description.attributes f"{self._attr_unique_id}_{system_zone_id}_{description.key}"
)
self.entity_description = description self.entity_description = description
@property
def extra_state_attributes(self) -> Mapping[str, Any] | None:
"""Return state attributes."""
if not self.attributes:
return None
return {key: self.get_zone_value(val) for key, val in self.attributes.items()}
@property
def is_on(self) -> bool | None:
"""Return true if the binary sensor is on."""
return self.get_zone_value(self.entity_description.key)

View File

@ -2,7 +2,7 @@
from __future__ import annotations from __future__ import annotations
import logging import logging
from typing import Final from typing import Any, Final
from aioairzone.common import OperationMode from aioairzone.common import OperationMode
from aioairzone.const import ( from aioairzone.const import (
@ -26,23 +26,12 @@ from aioairzone.const import (
AZD_ZONES, AZD_ZONES,
) )
from aioairzone.exceptions import AirzoneError from aioairzone.exceptions import AirzoneError
from aiohttp.client_exceptions import ClientConnectorError
from homeassistant.components.climate import ClimateEntity from homeassistant.components.climate import ClimateEntity
from homeassistant.components.climate.const import ( from homeassistant.components.climate.const import (
CURRENT_HVAC_COOL, ClimateEntityFeature,
CURRENT_HVAC_DRY, HVACAction,
CURRENT_HVAC_FAN, HVACMode,
CURRENT_HVAC_HEAT,
CURRENT_HVAC_IDLE,
CURRENT_HVAC_OFF,
HVAC_MODE_COOL,
HVAC_MODE_DRY,
HVAC_MODE_FAN_ONLY,
HVAC_MODE_HEAT,
HVAC_MODE_HEAT_COOL,
HVAC_MODE_OFF,
SUPPORT_TARGET_TEMPERATURE,
) )
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ATTR_TEMPERATURE from homeassistant.const import ATTR_TEMPERATURE
@ -50,35 +39,35 @@ from homeassistant.core import HomeAssistant, callback
from homeassistant.exceptions import HomeAssistantError from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AirzoneEntity from . import AirzoneZoneEntity
from .const import API_TEMPERATURE_STEP, DOMAIN, TEMP_UNIT_LIB_TO_HASS from .const import API_TEMPERATURE_STEP, DOMAIN, TEMP_UNIT_LIB_TO_HASS
from .coordinator import AirzoneUpdateCoordinator from .coordinator import AirzoneUpdateCoordinator
_LOGGER = logging.getLogger(__name__) _LOGGER = logging.getLogger(__name__)
HVAC_ACTION_LIB_TO_HASS: Final[dict[OperationMode, str]] = { HVAC_ACTION_LIB_TO_HASS: Final[dict[OperationMode, HVACAction]] = {
OperationMode.STOP: CURRENT_HVAC_OFF, OperationMode.STOP: HVACAction.OFF,
OperationMode.COOLING: CURRENT_HVAC_COOL, OperationMode.COOLING: HVACAction.COOLING,
OperationMode.HEATING: CURRENT_HVAC_HEAT, OperationMode.HEATING: HVACAction.HEATING,
OperationMode.FAN: CURRENT_HVAC_FAN, OperationMode.FAN: HVACAction.FAN,
OperationMode.DRY: CURRENT_HVAC_DRY, OperationMode.DRY: HVACAction.DRYING,
} }
HVAC_MODE_LIB_TO_HASS: Final[dict[OperationMode, str]] = { HVAC_MODE_LIB_TO_HASS: Final[dict[OperationMode, HVACMode]] = {
OperationMode.STOP: HVAC_MODE_OFF, OperationMode.STOP: HVACMode.OFF,
OperationMode.COOLING: HVAC_MODE_COOL, OperationMode.COOLING: HVACMode.COOL,
OperationMode.HEATING: HVAC_MODE_HEAT, OperationMode.HEATING: HVACMode.HEAT,
OperationMode.FAN: HVAC_MODE_FAN_ONLY, OperationMode.FAN: HVACMode.FAN_ONLY,
OperationMode.DRY: HVAC_MODE_DRY, OperationMode.DRY: HVACMode.DRY,
OperationMode.AUTO: HVAC_MODE_HEAT_COOL, OperationMode.AUTO: HVACMode.HEAT_COOL,
} }
HVAC_MODE_HASS_TO_LIB: Final[dict[str, OperationMode]] = { HVAC_MODE_HASS_TO_LIB: Final[dict[HVACMode, OperationMode]] = {
HVAC_MODE_OFF: OperationMode.STOP, HVACMode.OFF: OperationMode.STOP,
HVAC_MODE_COOL: OperationMode.COOLING, HVACMode.COOL: OperationMode.COOLING,
HVAC_MODE_HEAT: OperationMode.HEATING, HVACMode.HEAT: OperationMode.HEATING,
HVAC_MODE_FAN_ONLY: OperationMode.FAN, HVACMode.FAN_ONLY: OperationMode.FAN,
HVAC_MODE_DRY: OperationMode.DRY, HVACMode.DRY: OperationMode.DRY,
HVAC_MODE_HEAT_COOL: OperationMode.AUTO, HVACMode.HEAT_COOL: OperationMode.AUTO,
} }
@ -98,7 +87,7 @@ async def async_setup_entry(
) )
class AirzoneClimate(AirzoneEntity, ClimateEntity): class AirzoneClimate(AirzoneZoneEntity, ClimateEntity):
"""Define an Airzone sensor.""" """Define an Airzone sensor."""
def __init__( def __init__(
@ -110,61 +99,74 @@ class AirzoneClimate(AirzoneEntity, ClimateEntity):
) -> None: ) -> None:
"""Initialize Airzone climate entity.""" """Initialize Airzone climate entity."""
super().__init__(coordinator, entry, system_zone_id, zone_data) super().__init__(coordinator, entry, system_zone_id, zone_data)
self._attr_name = f"{zone_data[AZD_NAME]}" self._attr_name = f"{zone_data[AZD_NAME]}"
self._attr_unique_id = f"{entry.entry_id}_{system_zone_id}" self._attr_unique_id = f"{self._attr_unique_id}_{system_zone_id}"
self._attr_supported_features = SUPPORT_TARGET_TEMPERATURE self._attr_supported_features = ClimateEntityFeature.TARGET_TEMPERATURE
self._attr_target_temperature_step = API_TEMPERATURE_STEP self._attr_target_temperature_step = API_TEMPERATURE_STEP
self._attr_max_temp = self.get_zone_value(AZD_TEMP_MAX) self._attr_max_temp = self.get_airzone_value(AZD_TEMP_MAX)
self._attr_min_temp = self.get_zone_value(AZD_TEMP_MIN) self._attr_min_temp = self.get_airzone_value(AZD_TEMP_MIN)
self._attr_temperature_unit = TEMP_UNIT_LIB_TO_HASS[ self._attr_temperature_unit = TEMP_UNIT_LIB_TO_HASS[
self.get_zone_value(AZD_TEMP_UNIT) self.get_airzone_value(AZD_TEMP_UNIT)
] ]
self._attr_hvac_modes = [ self._attr_hvac_modes = [
HVAC_MODE_LIB_TO_HASS[mode] for mode in self.get_zone_value(AZD_MODES) HVAC_MODE_LIB_TO_HASS[mode] for mode in self.get_airzone_value(AZD_MODES)
] ]
self._async_update_attrs() self._async_update_attrs()
async def _async_update_hvac_params(self, params) -> None: async def _async_update_hvac_params(self, params: dict[str, Any]) -> None:
"""Send HVAC parameters to API.""" """Send HVAC parameters to API."""
_params = {
API_SYSTEM_ID: self.system_id,
API_ZONE_ID: self.zone_id,
**params,
}
_LOGGER.debug("update_hvac_params=%s", _params)
try: try:
await self.coordinator.airzone.put_hvac(params) await self.coordinator.airzone.put_hvac(_params)
except (AirzoneError, ClientConnectorError) as error: except AirzoneError as error:
raise HomeAssistantError( raise HomeAssistantError(
f"Failed to set zone {self.name}: {error}" f"Failed to set zone {self.name}: {error}"
) from error ) from error
else: else:
self.coordinator.async_set_updated_data(self.coordinator.airzone.data()) self.coordinator.async_set_updated_data(self.coordinator.airzone.data())
async def async_set_hvac_mode(self, hvac_mode: str) -> None: async def async_turn_on(self) -> None:
"""Set hvac mode.""" """Turn the entity on."""
params = { params = {
API_SYSTEM_ID: self.system_id, API_ON: 1,
API_ZONE_ID: self.zone_id,
} }
if hvac_mode == HVAC_MODE_OFF: await self._async_update_hvac_params(params)
async def async_turn_off(self) -> None:
"""Turn the entity off."""
params = {
API_ON: 0,
}
await self._async_update_hvac_params(params)
async def async_set_hvac_mode(self, hvac_mode: HVACMode) -> None:
"""Set hvac mode."""
params = {}
if hvac_mode == HVACMode.OFF:
params[API_ON] = 0 params[API_ON] = 0
else: else:
mode = HVAC_MODE_HASS_TO_LIB[hvac_mode] mode = HVAC_MODE_HASS_TO_LIB[hvac_mode]
if mode != self.get_zone_value(AZD_MODE): if mode != self.get_airzone_value(AZD_MODE):
if self.get_zone_value(AZD_MASTER): if self.get_airzone_value(AZD_MASTER):
params[API_MODE] = mode params[API_MODE] = mode
else: else:
raise HomeAssistantError( raise HomeAssistantError(
f"Mode can't be changed on slave zone {self.name}" f"Mode can't be changed on slave zone {self.name}"
) )
params[API_ON] = 1 params[API_ON] = 1
_LOGGER.debug("Set hvac_mode=%s params=%s", hvac_mode, params)
await self._async_update_hvac_params(params) await self._async_update_hvac_params(params)
async def async_set_temperature(self, **kwargs) -> None: async def async_set_temperature(self, **kwargs) -> None:
"""Set new target temperature.""" """Set new target temperature."""
temp = kwargs.get(ATTR_TEMPERATURE)
params = { params = {
API_SYSTEM_ID: self.system_id, API_SET_POINT: kwargs.get(ATTR_TEMPERATURE),
API_ZONE_ID: self.zone_id,
API_SET_POINT: temp,
} }
_LOGGER.debug("Set temp=%s params=%s", temp, params)
await self._async_update_hvac_params(params) await self._async_update_hvac_params(params)
@callback @callback
@ -176,16 +178,16 @@ class AirzoneClimate(AirzoneEntity, ClimateEntity):
@callback @callback
def _async_update_attrs(self) -> None: def _async_update_attrs(self) -> None:
"""Update climate attributes.""" """Update climate attributes."""
self._attr_current_temperature = self.get_zone_value(AZD_TEMP) self._attr_current_temperature = self.get_airzone_value(AZD_TEMP)
self._attr_current_humidity = self.get_zone_value(AZD_HUMIDITY) self._attr_current_humidity = self.get_airzone_value(AZD_HUMIDITY)
if self.get_zone_value(AZD_ON): if self.get_airzone_value(AZD_ON):
mode = self.get_zone_value(AZD_MODE) mode = self.get_airzone_value(AZD_MODE)
self._attr_hvac_mode = HVAC_MODE_LIB_TO_HASS[mode] self._attr_hvac_mode = HVAC_MODE_LIB_TO_HASS[mode]
if self.get_zone_value(AZD_DEMAND): if self.get_airzone_value(AZD_DEMAND):
self._attr_hvac_action = HVAC_ACTION_LIB_TO_HASS[mode] self._attr_hvac_action = HVAC_ACTION_LIB_TO_HASS[mode]
else: else:
self._attr_hvac_action = CURRENT_HVAC_IDLE self._attr_hvac_action = HVACAction.IDLE
else: else:
self._attr_hvac_action = CURRENT_HVAC_OFF self._attr_hvac_action = HVACAction.OFF
self._attr_hvac_mode = HVAC_MODE_OFF self._attr_hvac_mode = HVACMode.OFF
self._attr_target_temperature = self.get_zone_value(AZD_TEMP_SET) self._attr_target_temperature = self.get_airzone_value(AZD_TEMP_SET)

View File

@ -3,18 +3,30 @@ from __future__ import annotations
from typing import Any from typing import Any
from aioairzone.common import ConnectionOptions from aioairzone.const import DEFAULT_PORT, DEFAULT_SYSTEM_ID
from aioairzone.exceptions import InvalidHost from aioairzone.exceptions import AirzoneError, InvalidSystem
from aioairzone.localapi import AirzoneLocalApi from aioairzone.localapi import AirzoneLocalApi, ConnectionOptions
from aiohttp.client_exceptions import ClientConnectorError
import voluptuous as vol import voluptuous as vol
from homeassistant import config_entries from homeassistant import config_entries
from homeassistant.const import CONF_HOST, CONF_PORT from homeassistant.const import CONF_HOST, CONF_ID, CONF_PORT
from homeassistant.data_entry_flow import FlowResult from homeassistant.data_entry_flow import FlowResult
from homeassistant.helpers import aiohttp_client from homeassistant.helpers import aiohttp_client
from homeassistant.helpers.device_registry import format_mac
from .const import DEFAULT_LOCAL_API_PORT, DOMAIN from .const import DOMAIN
CONFIG_SCHEMA = vol.Schema(
{
vol.Required(CONF_HOST): str,
vol.Required(CONF_PORT, default=DEFAULT_PORT): int,
}
)
SYSTEM_ID_SCHEMA = CONFIG_SCHEMA.extend(
{
vol.Required(CONF_ID, default=1): int,
}
)
class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN): class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
@ -24,39 +36,43 @@ class ConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
self, user_input: dict[str, Any] | None = None self, user_input: dict[str, Any] | None = None
) -> FlowResult: ) -> FlowResult:
"""Handle the initial step.""" """Handle the initial step."""
data_schema = CONFIG_SCHEMA
errors = {} errors = {}
if user_input is not None: if user_input is not None:
self._async_abort_entries_match( self._async_abort_entries_match(user_input)
{
CONF_HOST: user_input[CONF_HOST],
CONF_PORT: user_input[CONF_PORT],
}
)
airzone = AirzoneLocalApi( airzone = AirzoneLocalApi(
aiohttp_client.async_get_clientsession(self.hass), aiohttp_client.async_get_clientsession(self.hass),
ConnectionOptions( ConnectionOptions(
user_input[CONF_HOST], user_input[CONF_HOST],
user_input[CONF_PORT], user_input[CONF_PORT],
user_input.get(CONF_ID, DEFAULT_SYSTEM_ID),
), ),
) )
try: try:
await airzone.validate_airzone() mac = await airzone.validate()
except (ClientConnectorError, InvalidHost): except InvalidSystem:
data_schema = SYSTEM_ID_SCHEMA
errors[CONF_ID] = "invalid_system_id"
except AirzoneError:
errors["base"] = "cannot_connect" errors["base"] = "cannot_connect"
else: else:
if mac:
await self.async_set_unique_id(format_mac(mac))
self._abort_if_unique_id_configured(
updates={
CONF_HOST: user_input[CONF_HOST],
CONF_PORT: user_input[CONF_PORT],
}
)
title = f"Airzone {user_input[CONF_HOST]}:{user_input[CONF_PORT]}" title = f"Airzone {user_input[CONF_HOST]}:{user_input[CONF_PORT]}"
return self.async_create_entry(title=title, data=user_input) return self.async_create_entry(title=title, data=user_input)
return self.async_show_form( return self.async_show_form(
step_id="user", step_id="user",
data_schema=vol.Schema( data_schema=data_schema,
{
vol.Required(CONF_HOST): str,
vol.Required(CONF_PORT, default=DEFAULT_LOCAL_API_PORT): int,
}
),
errors=errors, errors=errors,
) )

View File

@ -11,7 +11,6 @@ MANUFACTURER: Final = "Airzone"
AIOAIRZONE_DEVICE_TIMEOUT_SEC: Final = 10 AIOAIRZONE_DEVICE_TIMEOUT_SEC: Final = 10
API_TEMPERATURE_STEP: Final = 0.5 API_TEMPERATURE_STEP: Final = 0.5
DEFAULT_LOCAL_API_PORT: Final = 3000
TEMP_UNIT_LIB_TO_HASS: Final[dict[TemperatureUnit, str]] = { TEMP_UNIT_LIB_TO_HASS: Final[dict[TemperatureUnit, str]] = {
TemperatureUnit.CELSIUS: TEMP_CELSIUS, TemperatureUnit.CELSIUS: TEMP_CELSIUS,

View File

@ -4,8 +4,8 @@ from __future__ import annotations
from datetime import timedelta from datetime import timedelta
import logging import logging
from aioairzone.exceptions import AirzoneError
from aioairzone.localapi import AirzoneLocalApi from aioairzone.localapi import AirzoneLocalApi
from aiohttp.client_exceptions import ClientConnectorError
import async_timeout import async_timeout
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
@ -36,7 +36,7 @@ class AirzoneUpdateCoordinator(DataUpdateCoordinator):
"""Update data via library.""" """Update data via library."""
async with async_timeout.timeout(AIOAIRZONE_DEVICE_TIMEOUT_SEC): async with async_timeout.timeout(AIOAIRZONE_DEVICE_TIMEOUT_SEC):
try: try:
await self.airzone.update_airzone() await self.airzone.update()
except ClientConnectorError as error: except AirzoneError as error:
raise UpdateFailed(error) from error raise UpdateFailed(error) from error
return self.airzone.data() return self.airzone.data()

View File

@ -0,0 +1,29 @@
"""Support for the Airzone diagnostics."""
from __future__ import annotations
from typing import Any
from aioairzone.const import AZD_MAC
from homeassistant.components.diagnostics.util import async_redact_data
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant
from .const import DOMAIN
from .coordinator import AirzoneUpdateCoordinator
TO_REDACT = [
AZD_MAC,
]
async def async_get_config_entry_diagnostics(
hass: HomeAssistant, config_entry: ConfigEntry
) -> dict[str, Any]:
"""Return diagnostics for a config entry."""
coordinator: AirzoneUpdateCoordinator = hass.data[DOMAIN][config_entry.entry_id]
return {
"info": async_redact_data(config_entry.data, TO_REDACT),
"data": async_redact_data(coordinator.data, TO_REDACT),
}

View File

@ -3,7 +3,7 @@
"name": "Airzone", "name": "Airzone",
"config_flow": true, "config_flow": true,
"documentation": "https://www.home-assistant.io/integrations/airzone", "documentation": "https://www.home-assistant.io/integrations/airzone",
"requirements": ["aioairzone==0.3.3"], "requirements": ["aioairzone==0.4.2"],
"codeowners": ["@Noltari"], "codeowners": ["@Noltari"],
"iot_class": "local_polling", "iot_class": "local_polling",
"loggers": ["aioairzone"] "loggers": ["aioairzone"]

View File

@ -6,38 +6,34 @@ from typing import Any, Final
from aioairzone.const import AZD_HUMIDITY, AZD_NAME, AZD_TEMP, AZD_TEMP_UNIT, AZD_ZONES from aioairzone.const import AZD_HUMIDITY, AZD_NAME, AZD_TEMP, AZD_TEMP_UNIT, AZD_ZONES
from homeassistant.components.sensor import ( from homeassistant.components.sensor import (
STATE_CLASS_MEASUREMENT, SensorDeviceClass,
SensorEntity, SensorEntity,
SensorEntityDescription, SensorEntityDescription,
SensorStateClass,
) )
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import ( from homeassistant.const import PERCENTAGE, TEMP_CELSIUS
DEVICE_CLASS_HUMIDITY,
DEVICE_CLASS_TEMPERATURE,
PERCENTAGE,
TEMP_CELSIUS,
)
from homeassistant.core import HomeAssistant from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.entity_platform import AddEntitiesCallback
from . import AirzoneEntity from . import AirzoneEntity, AirzoneZoneEntity
from .const import DOMAIN, TEMP_UNIT_LIB_TO_HASS from .const import DOMAIN, TEMP_UNIT_LIB_TO_HASS
from .coordinator import AirzoneUpdateCoordinator from .coordinator import AirzoneUpdateCoordinator
SENSOR_TYPES: Final[tuple[SensorEntityDescription, ...]] = ( ZONE_SENSOR_TYPES: Final[tuple[SensorEntityDescription, ...]] = (
SensorEntityDescription( SensorEntityDescription(
device_class=DEVICE_CLASS_TEMPERATURE, device_class=SensorDeviceClass.TEMPERATURE,
key=AZD_TEMP, key=AZD_TEMP,
name="Temperature", name="Temperature",
native_unit_of_measurement=TEMP_CELSIUS, native_unit_of_measurement=TEMP_CELSIUS,
state_class=STATE_CLASS_MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
), ),
SensorEntityDescription( SensorEntityDescription(
device_class=DEVICE_CLASS_HUMIDITY, device_class=SensorDeviceClass.HUMIDITY,
key=AZD_HUMIDITY, key=AZD_HUMIDITY,
name="Humidity", name="Humidity",
native_unit_of_measurement=PERCENTAGE, native_unit_of_measurement=PERCENTAGE,
state_class=STATE_CLASS_MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
), ),
) )
@ -48,12 +44,12 @@ async def async_setup_entry(
"""Add Airzone sensors from a config_entry.""" """Add Airzone sensors from a config_entry."""
coordinator = hass.data[DOMAIN][entry.entry_id] coordinator = hass.data[DOMAIN][entry.entry_id]
sensors = [] sensors: list[AirzoneSensor] = []
for system_zone_id, zone_data in coordinator.data[AZD_ZONES].items(): for system_zone_id, zone_data in coordinator.data[AZD_ZONES].items():
for description in SENSOR_TYPES: for description in ZONE_SENSOR_TYPES:
if description.key in zone_data: if description.key in zone_data:
sensors.append( sensors.append(
AirzoneSensor( AirzoneZoneSensor(
coordinator, coordinator,
description, description,
entry, entry,
@ -68,6 +64,15 @@ async def async_setup_entry(
class AirzoneSensor(AirzoneEntity, SensorEntity): class AirzoneSensor(AirzoneEntity, SensorEntity):
"""Define an Airzone sensor.""" """Define an Airzone sensor."""
@property
def native_value(self):
"""Return the state."""
return self.get_airzone_value(self.entity_description.key)
class AirzoneZoneSensor(AirzoneZoneEntity, AirzoneSensor):
"""Define an Airzone Zone sensor."""
def __init__( def __init__(
self, self,
coordinator: AirzoneUpdateCoordinator, coordinator: AirzoneUpdateCoordinator,
@ -78,16 +83,14 @@ class AirzoneSensor(AirzoneEntity, SensorEntity):
) -> None: ) -> None:
"""Initialize.""" """Initialize."""
super().__init__(coordinator, entry, system_zone_id, zone_data) super().__init__(coordinator, entry, system_zone_id, zone_data)
self._attr_name = f"{zone_data[AZD_NAME]} {description.name}" self._attr_name = f"{zone_data[AZD_NAME]} {description.name}"
self._attr_unique_id = f"{entry.entry_id}_{system_zone_id}_{description.key}" self._attr_unique_id = (
f"{self._attr_unique_id}_{system_zone_id}_{description.key}"
)
self.entity_description = description self.entity_description = description
if description.key == AZD_TEMP: if description.key == AZD_TEMP:
self._attr_native_unit_of_measurement = TEMP_UNIT_LIB_TO_HASS.get( self._attr_native_unit_of_measurement = TEMP_UNIT_LIB_TO_HASS.get(
self.get_zone_value(AZD_TEMP_UNIT) self.get_airzone_value(AZD_TEMP_UNIT)
) )
@property
def native_value(self):
"""Return the state."""
return self.get_zone_value(self.entity_description.key)

View File

@ -4,7 +4,8 @@
"already_configured": "[%key:common::config_flow::abort::already_configured_device%]" "already_configured": "[%key:common::config_flow::abort::already_configured_device%]"
}, },
"error": { "error": {
"cannot_connect": "[%key:common::config_flow::error::cannot_connect%]" "cannot_connect": "[%key:common::config_flow::error::cannot_connect%]",
"invalid_system_id": "Invalid Airzone System ID"
}, },
"step": { "step": {
"user": { "user": {

Some files were not shown because too many files have changed in this diff Show More