homeassistant 2025.7.0b0__py3-none-any.whl → 2025.7.0b2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- homeassistant/components/aemet/sensor.py +1 -1
- homeassistant/components/airq/coordinator.py +2 -2
- homeassistant/components/alexa_devices/__init__.py +5 -2
- homeassistant/components/alexa_devices/notify.py +2 -0
- homeassistant/components/alexa_devices/quality_scale.yaml +1 -1
- homeassistant/components/alexa_devices/strings.json +11 -4
- homeassistant/components/alexa_devices/switch.py +2 -0
- homeassistant/components/alexa_devices/translations/bg.json +6 -4
- homeassistant/components/alexa_devices/translations/cs.json +12 -5
- homeassistant/components/alexa_devices/translations/de.json +14 -7
- homeassistant/components/alexa_devices/translations/el.json +12 -5
- homeassistant/components/alexa_devices/translations/en.json +12 -5
- homeassistant/components/alexa_devices/translations/es.json +12 -5
- homeassistant/components/alexa_devices/translations/et.json +12 -5
- homeassistant/components/alexa_devices/translations/ga.json +0 -6
- homeassistant/components/alexa_devices/translations/he.json +0 -4
- homeassistant/components/alexa_devices/translations/hu.json +0 -4
- homeassistant/components/alexa_devices/translations/id.json +1 -0
- homeassistant/components/alexa_devices/translations/lt.json +0 -4
- homeassistant/components/alexa_devices/translations/mk.json +12 -0
- homeassistant/components/alexa_devices/translations/nl.json +0 -4
- homeassistant/components/alexa_devices/translations/pl.json +0 -4
- homeassistant/components/alexa_devices/translations/pt.json +0 -4
- homeassistant/components/alexa_devices/translations/ru.json +4 -5
- homeassistant/components/alexa_devices/translations/sk.json +12 -5
- homeassistant/components/alexa_devices/translations/sv.json +17 -5
- homeassistant/components/alexa_devices/translations/tr.json +0 -4
- homeassistant/components/alexa_devices/translations/zh-Hans.json +27 -5
- homeassistant/components/alexa_devices/translations/zh-Hant.json +12 -5
- homeassistant/components/alexa_devices/utils.py +40 -0
- homeassistant/components/altruist/translations/id.json +11 -0
- homeassistant/components/anthropic/__init__.py +14 -1
- homeassistant/components/anthropic/translations/bg.json +21 -0
- homeassistant/components/anthropic/translations/ga.json +32 -1
- homeassistant/components/anthropic/translations/id.json +19 -0
- homeassistant/components/anthropic/translations/ru.json +30 -0
- homeassistant/components/backup/translations/de.json +1 -1
- homeassistant/components/buienradar/sensor.py +0 -1
- homeassistant/components/cambridge_audio/translations/sv.json +1 -1
- homeassistant/components/comelit/translations/de.json +1 -1
- homeassistant/components/counter/translations/sv.json +2 -2
- homeassistant/components/demo/translations/select.sv.json +2 -2
- homeassistant/components/derivative/translations/ga.json +20 -0
- homeassistant/components/derivative/translations/ru.json +3 -0
- homeassistant/components/devolo_home_control/translations/bg.json +6 -0
- homeassistant/components/devolo_home_control/translations/id.json +5 -0
- homeassistant/components/devolo_home_control/translations/sv.json +10 -0
- homeassistant/components/devolo_home_control/translations/zh-Hans.json +10 -0
- homeassistant/components/dlink/manifest.json +1 -1
- homeassistant/components/ecovacs/translations/sv.json +1 -1
- homeassistant/components/enphase_envoy/translations/sv.json +5 -2
- homeassistant/components/ezviz/translations/bg.json +6 -0
- homeassistant/components/ezviz/translations/mk.json +13 -0
- homeassistant/components/ezviz/translations/sv.json +10 -0
- homeassistant/components/ezviz/translations/zh-Hans.json +10 -0
- homeassistant/components/fronius/translations/sv.json +2 -2
- homeassistant/components/frontend/manifest.json +1 -1
- homeassistant/components/goodwe/translations/sv.json +5 -5
- homeassistant/components/google_generative_ai_conversation/__init__.py +21 -0
- homeassistant/components/google_generative_ai_conversation/config_flow.py +72 -36
- homeassistant/components/google_generative_ai_conversation/const.py +15 -2
- homeassistant/components/google_generative_ai_conversation/diagnostics.py +1 -0
- homeassistant/components/google_generative_ai_conversation/entity.py +7 -2
- homeassistant/components/google_generative_ai_conversation/helpers.py +73 -0
- homeassistant/components/google_generative_ai_conversation/strings.json +28 -1
- homeassistant/components/google_generative_ai_conversation/translations/bg.json +19 -0
- homeassistant/components/google_generative_ai_conversation/translations/cs.json +28 -0
- homeassistant/components/google_generative_ai_conversation/translations/de.json +28 -0
- homeassistant/components/google_generative_ai_conversation/translations/el.json +28 -0
- homeassistant/components/google_generative_ai_conversation/translations/en.json +28 -0
- homeassistant/components/google_generative_ai_conversation/translations/es.json +28 -0
- homeassistant/components/google_generative_ai_conversation/translations/et.json +28 -0
- homeassistant/components/google_generative_ai_conversation/translations/ga.json +9 -0
- homeassistant/components/google_generative_ai_conversation/translations/id.json +30 -0
- homeassistant/components/google_generative_ai_conversation/translations/mk.json +11 -0
- homeassistant/components/google_generative_ai_conversation/translations/ru.json +67 -0
- homeassistant/components/google_generative_ai_conversation/translations/sk.json +28 -0
- homeassistant/components/google_generative_ai_conversation/translations/sv.json +23 -0
- homeassistant/components/google_generative_ai_conversation/translations/zh-Hans.json +28 -0
- homeassistant/components/google_generative_ai_conversation/translations/zh-Hant.json +28 -0
- homeassistant/components/google_generative_ai_conversation/tts.py +48 -106
- homeassistant/components/group/translations/el.json +18 -18
- homeassistant/components/habitica/const.py +1 -1
- homeassistant/components/harmony/translations/select.sv.json +1 -1
- homeassistant/components/harmony/translations/sv.json +1 -1
- homeassistant/components/homeassistant_hardware/firmware_config_flow.py +89 -7
- homeassistant/components/homeassistant_hardware/strings.json +2 -1
- homeassistant/components/homeassistant_hardware/translations/de.json +1 -0
- homeassistant/components/homeassistant_hardware/translations/en-GB.json +1 -0
- homeassistant/components/homeassistant_hardware/translations/en.json +1 -0
- homeassistant/components/homeassistant_hardware/translations/ga.json +9 -0
- homeassistant/components/homeassistant_hardware/translations/mk.json +9 -0
- homeassistant/components/homeassistant_sky_connect/config_flow.py +1 -1
- homeassistant/components/homeassistant_sky_connect/strings.json +4 -2
- homeassistant/components/homeassistant_sky_connect/translations/de.json +2 -0
- homeassistant/components/homeassistant_sky_connect/translations/en-GB.json +2 -0
- homeassistant/components/homeassistant_sky_connect/translations/en.json +2 -0
- homeassistant/components/homeassistant_sky_connect/translations/ga.json +10 -0
- homeassistant/components/homeassistant_sky_connect/translations/mk.json +7 -0
- homeassistant/components/homeassistant_yellow/strings.json +2 -1
- homeassistant/components/homeassistant_yellow/translations/bg.json +0 -1
- homeassistant/components/homeassistant_yellow/translations/cs.json +0 -1
- homeassistant/components/homeassistant_yellow/translations/de.json +1 -0
- homeassistant/components/homeassistant_yellow/translations/el.json +0 -1
- homeassistant/components/homeassistant_yellow/translations/en-GB.json +2 -1
- homeassistant/components/homeassistant_yellow/translations/en.json +2 -1
- homeassistant/components/homeassistant_yellow/translations/es.json +0 -1
- homeassistant/components/homeassistant_yellow/translations/et.json +0 -1
- homeassistant/components/homeassistant_yellow/translations/fr.json +0 -1
- homeassistant/components/homeassistant_yellow/translations/ga.json +5 -0
- homeassistant/components/homeassistant_yellow/translations/he.json +0 -1
- homeassistant/components/homeassistant_yellow/translations/hu.json +0 -1
- homeassistant/components/homeassistant_yellow/translations/id.json +0 -1
- homeassistant/components/homeassistant_yellow/translations/it.json +0 -1
- homeassistant/components/homeassistant_yellow/translations/ja.json +0 -1
- homeassistant/components/homeassistant_yellow/translations/lt.json +0 -1
- homeassistant/components/homeassistant_yellow/translations/pt.json +0 -1
- homeassistant/components/homeassistant_yellow/translations/ru.json +0 -1
- homeassistant/components/homeassistant_yellow/translations/sk.json +0 -1
- homeassistant/components/homeassistant_yellow/translations/sv.json +0 -1
- homeassistant/components/homeassistant_yellow/translations/tr.json +0 -1
- homeassistant/components/homeassistant_yellow/translations/zh-Hans.json +0 -1
- homeassistant/components/homeassistant_yellow/translations/zh-Hant.json +0 -1
- homeassistant/components/homewizard/translations/sv.json +3 -1
- homeassistant/components/http/auth.py +1 -1
- homeassistant/components/image/__init__.py +34 -3
- homeassistant/components/input_number/translations/sv.json +2 -2
- homeassistant/components/input_select/translations/sv.json +6 -6
- homeassistant/components/input_text/translations/sv.json +1 -1
- homeassistant/components/iron_os/manifest.json +1 -1
- homeassistant/components/iron_os/translations/sv.json +1 -1
- homeassistant/components/keenetic_ndms2/translations/id.json +3 -0
- homeassistant/components/lamarzocco/entity.py +19 -1
- homeassistant/components/lamarzocco/number.py +0 -4
- homeassistant/components/lamarzocco/sensor.py +2 -4
- homeassistant/components/lamarzocco/translations/sv.json +3 -3
- homeassistant/components/lametric/translations/sv.json +2 -2
- homeassistant/components/lametric/update.py +1 -1
- homeassistant/components/lg_thinq/translations/sv.json +5 -5
- homeassistant/components/litterrobot/translations/bg.json +4 -0
- homeassistant/components/litterrobot/translations/ga.json +3 -0
- homeassistant/components/matter/translations/id.json +5 -0
- homeassistant/components/matter/vacuum.py +38 -26
- homeassistant/components/meater/__init__.py +5 -1
- homeassistant/components/meater/coordinator.py +4 -2
- homeassistant/components/media_source/local_source.py +21 -4
- homeassistant/components/minecraft_server/translations/sv.json +1 -1
- homeassistant/components/motioneye/translations/sv.json +1 -1
- homeassistant/components/mqtt/translations/bg.json +10 -0
- homeassistant/components/mqtt/translations/cs.json +19 -0
- homeassistant/components/mqtt/translations/el.json +21 -0
- homeassistant/components/mqtt/translations/fi.json +3 -0
- homeassistant/components/mqtt/translations/ga.json +25 -0
- homeassistant/components/mqtt/translations/mk.json +23 -0
- homeassistant/components/mqtt/translations/ru.json +1 -0
- homeassistant/components/mqtt/translations/sv.json +24 -0
- homeassistant/components/mqtt/translations/zh-Hans.json +26 -0
- homeassistant/components/mqtt/translations/zh-Hant.json +19 -0
- homeassistant/components/music_assistant/button.py +0 -6
- homeassistant/components/ntfy/translations/id.json +13 -0
- homeassistant/components/ntfy/translations/sv.json +1 -0
- homeassistant/components/number/translations/sv.json +2 -2
- homeassistant/components/nut/config_flow.py +4 -2
- homeassistant/components/ohme/translations/sv.json +1 -1
- homeassistant/components/ollama/__init__.py +8 -0
- homeassistant/components/ollama/const.py +2 -0
- homeassistant/components/ollama/translations/bg.json +19 -0
- homeassistant/components/ollama/translations/ga.json +31 -1
- homeassistant/components/ollama/translations/id.json +18 -0
- homeassistant/components/ollama/translations/mk.json +13 -1
- homeassistant/components/ollama/translations/sv.json +1 -0
- homeassistant/components/onewire/translations/sv.json +4 -4
- homeassistant/components/openai_conversation/__init__.py +8 -0
- homeassistant/components/openai_conversation/const.py +1 -1
- homeassistant/components/openai_conversation/conversation.py +1 -1
- homeassistant/components/openai_conversation/translations/bg.json +26 -0
- homeassistant/components/openai_conversation/translations/id.json +23 -0
- homeassistant/components/openai_conversation/translations/mk.json +44 -0
- homeassistant/components/openai_conversation/translations/sv.json +4 -0
- homeassistant/components/playstation_network/diagnostics.py +55 -0
- homeassistant/components/playstation_network/quality_scale.yaml +1 -1
- homeassistant/components/playstation_network/translations/bg.json +25 -1
- homeassistant/components/playstation_network/translations/es.json +1 -1
- homeassistant/components/playstation_network/translations/ga.json +31 -0
- homeassistant/components/playstation_network/translations/id.json +14 -0
- homeassistant/components/playstation_network/translations/mk.json +18 -0
- homeassistant/components/playstation_network/translations/pl.json +73 -0
- homeassistant/components/playstation_network/translations/sv.json +29 -0
- homeassistant/components/playstation_network/translations/zh-Hans.json +29 -0
- homeassistant/components/plugwise/translations/sv.json +2 -2
- homeassistant/components/qnap/translations/sv.json +1 -1
- homeassistant/components/random/translations/sv.json +4 -4
- homeassistant/components/remote_calendar/translations/fi.json +34 -0
- homeassistant/components/select/translations/sv.json +10 -10
- homeassistant/components/smarla/__init__.py +2 -2
- homeassistant/components/sonos/translations/bg.json +5 -0
- homeassistant/components/sonos/translations/cs.json +6 -0
- homeassistant/components/sonos/translations/el.json +6 -0
- homeassistant/components/sonos/translations/ga.json +8 -0
- homeassistant/components/sonos/translations/mk.json +10 -0
- homeassistant/components/sonos/translations/ru.json +6 -0
- homeassistant/components/sonos/translations/sv.json +6 -0
- homeassistant/components/sonos/translations/zh-Hans.json +9 -0
- homeassistant/components/sonos/translations/zh-Hant.json +6 -0
- homeassistant/components/subaru/strings.json +2 -2
- homeassistant/components/subaru/translations/ca.json +0 -1
- homeassistant/components/subaru/translations/cs.json +0 -2
- homeassistant/components/subaru/translations/de.json +2 -2
- homeassistant/components/subaru/translations/el.json +0 -2
- homeassistant/components/subaru/translations/en-GB.json +0 -2
- homeassistant/components/subaru/translations/en.json +2 -2
- homeassistant/components/subaru/translations/es.json +0 -2
- homeassistant/components/subaru/translations/et.json +0 -2
- homeassistant/components/subaru/translations/fi.json +0 -1
- homeassistant/components/subaru/translations/hu.json +0 -2
- homeassistant/components/subaru/translations/it.json +0 -1
- homeassistant/components/subaru/translations/ja.json +0 -1
- homeassistant/components/subaru/translations/ko.json +0 -1
- homeassistant/components/subaru/translations/lt.json +0 -2
- homeassistant/components/subaru/translations/pt-BR.json +0 -1
- homeassistant/components/subaru/translations/pt.json +0 -2
- homeassistant/components/subaru/translations/ru.json +0 -2
- homeassistant/components/subaru/translations/sk.json +0 -2
- homeassistant/components/subaru/translations/sv.json +0 -2
- homeassistant/components/subaru/translations/tr.json +0 -2
- homeassistant/components/subaru/translations/zh-Hans.json +0 -2
- homeassistant/components/subaru/translations/zh-Hant.json +0 -2
- homeassistant/components/switchbot/translations/bg.json +26 -0
- homeassistant/components/switchbot/translations/ga.json +33 -0
- homeassistant/components/switchbot/translations/id.json +19 -0
- homeassistant/components/switchbot/translations/mk.json +49 -0
- homeassistant/components/switchbot/translations/sv.json +54 -0
- homeassistant/components/switchbot/translations/zh-Hans.json +53 -0
- homeassistant/components/telegram_bot/__init__.py +20 -4
- homeassistant/components/telegram_bot/bot.py +33 -29
- homeassistant/components/telegram_bot/config_flow.py +66 -20
- homeassistant/components/telegram_bot/const.py +1 -1
- homeassistant/components/telegram_bot/strings.json +33 -10
- homeassistant/components/telegram_bot/translations/bg.json +0 -1
- homeassistant/components/telegram_bot/translations/cs.json +35 -12
- homeassistant/components/telegram_bot/translations/de.json +35 -12
- homeassistant/components/telegram_bot/translations/el.json +35 -12
- homeassistant/components/telegram_bot/translations/en-GB.json +6 -11
- homeassistant/components/telegram_bot/translations/en.json +35 -12
- homeassistant/components/telegram_bot/translations/es.json +35 -12
- homeassistant/components/telegram_bot/translations/et.json +34 -11
- homeassistant/components/telegram_bot/translations/fr.json +5 -12
- homeassistant/components/telegram_bot/translations/ga.json +5 -11
- homeassistant/components/telegram_bot/translations/he.json +3 -8
- homeassistant/components/telegram_bot/translations/hu.json +5 -12
- homeassistant/components/telegram_bot/translations/id.json +0 -5
- homeassistant/components/telegram_bot/translations/it.json +2 -5
- homeassistant/components/telegram_bot/translations/lt.json +5 -12
- homeassistant/components/telegram_bot/translations/mk.json +7 -5
- homeassistant/components/telegram_bot/translations/nl.json +5 -12
- homeassistant/components/telegram_bot/translations/pt.json +5 -12
- homeassistant/components/telegram_bot/translations/ru.json +12 -11
- homeassistant/components/telegram_bot/translations/sk.json +35 -12
- homeassistant/components/telegram_bot/translations/sv.json +28 -12
- homeassistant/components/telegram_bot/translations/tr.json +5 -12
- homeassistant/components/telegram_bot/translations/zh-Hans.json +35 -12
- homeassistant/components/telegram_bot/translations/zh-Hant.json +35 -12
- homeassistant/components/template/translations/sv.json +5 -5
- homeassistant/components/text/translations/sv.json +1 -1
- homeassistant/components/tilt_pi/translations/id.json +11 -0
- homeassistant/components/tts/__init__.py +15 -0
- homeassistant/components/unifiprotect/translations/zh-Hans.json +3 -3
- homeassistant/components/utility_meter/translations/sv.json +9 -9
- homeassistant/components/vegehub/translations/bg.json +2 -0
- homeassistant/components/vegehub/translations/id.json +11 -0
- homeassistant/components/vegehub/translations/sv.json +2 -1
- homeassistant/components/vicare/translations/sv.json +2 -2
- homeassistant/components/whirlpool/translations/sv.json +12 -12
- homeassistant/components/wyoming/translations/sv.json +2 -2
- homeassistant/components/zha/translations/bg.json +23 -0
- homeassistant/components/zha/translations/el.json +10 -0
- homeassistant/components/zha/translations/ga.json +20 -0
- homeassistant/components/zha/translations/id.json +6 -0
- homeassistant/components/zha/translations/sv.json +23 -0
- homeassistant/components/zha/translations/zh-Hans.json +50 -0
- homeassistant/components/zwave_js/api.py +1 -1
- homeassistant/components/zwave_js/config_flow.py +15 -68
- homeassistant/components/zwave_js/manifest.json +1 -1
- homeassistant/components/zwave_js/strings.json +1 -5
- homeassistant/components/zwave_js/translations/bg.json +0 -3
- homeassistant/components/zwave_js/translations/cs.json +0 -5
- homeassistant/components/zwave_js/translations/de.json +1 -5
- homeassistant/components/zwave_js/translations/el.json +0 -5
- homeassistant/components/zwave_js/translations/en-GB.json +1 -5
- homeassistant/components/zwave_js/translations/en.json +1 -5
- homeassistant/components/zwave_js/translations/es.json +1 -5
- homeassistant/components/zwave_js/translations/et.json +0 -5
- homeassistant/components/zwave_js/translations/ga.json +0 -5
- homeassistant/components/zwave_js/translations/hu.json +0 -5
- homeassistant/components/zwave_js/translations/lt.json +0 -5
- homeassistant/components/zwave_js/translations/mk.json +0 -5
- homeassistant/components/zwave_js/translations/pt.json +0 -5
- homeassistant/components/zwave_js/translations/ru.json +0 -5
- homeassistant/components/zwave_js/translations/sk.json +0 -5
- homeassistant/components/zwave_js/translations/sv.json +0 -5
- homeassistant/components/zwave_js/translations/zh-Hans.json +0 -5
- homeassistant/components/zwave_js/translations/zh-Hant.json +1 -5
- homeassistant/config_entries.py +6 -0
- homeassistant/const.py +1 -1
- homeassistant/package_constraints.txt +1 -1
- {homeassistant-2025.7.0b0.dist-info → homeassistant-2025.7.0b2.dist-info}/METADATA +1 -1
- {homeassistant-2025.7.0b0.dist-info → homeassistant-2025.7.0b2.dist-info}/RECORD +312 -294
- {homeassistant-2025.7.0b0.dist-info → homeassistant-2025.7.0b2.dist-info}/WHEEL +0 -0
- {homeassistant-2025.7.0b0.dist-info → homeassistant-2025.7.0b2.dist-info}/entry_points.txt +0 -0
- {homeassistant-2025.7.0b0.dist-info → homeassistant-2025.7.0b2.dist-info}/licenses/LICENSE.md +0 -0
- {homeassistant-2025.7.0b0.dist-info → homeassistant-2025.7.0b2.dist-info}/licenses/homeassistant/backports/LICENSE.Python +0 -0
- {homeassistant-2025.7.0b0.dist-info → homeassistant-2025.7.0b2.dist-info}/top_level.txt +0 -0
|
@@ -2,13 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
-
from
|
|
6
|
-
import io
|
|
7
|
-
import logging
|
|
5
|
+
from collections.abc import Mapping
|
|
8
6
|
from typing import Any
|
|
9
|
-
import wave
|
|
10
7
|
|
|
11
8
|
from google.genai import types
|
|
9
|
+
from google.genai.errors import APIError, ClientError
|
|
10
|
+
from propcache.api import cached_property
|
|
12
11
|
|
|
13
12
|
from homeassistant.components.tts import (
|
|
14
13
|
ATTR_VOICE,
|
|
@@ -16,15 +15,14 @@ from homeassistant.components.tts import (
|
|
|
16
15
|
TtsAudioType,
|
|
17
16
|
Voice,
|
|
18
17
|
)
|
|
19
|
-
from homeassistant.config_entries import ConfigEntry
|
|
18
|
+
from homeassistant.config_entries import ConfigEntry, ConfigSubentry
|
|
20
19
|
from homeassistant.core import HomeAssistant, callback
|
|
21
20
|
from homeassistant.exceptions import HomeAssistantError
|
|
22
|
-
from homeassistant.helpers import device_registry as dr
|
|
23
21
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
|
24
22
|
|
|
25
|
-
from .const import
|
|
26
|
-
|
|
27
|
-
|
|
23
|
+
from .const import CONF_CHAT_MODEL, LOGGER, RECOMMENDED_TTS_MODEL
|
|
24
|
+
from .entity import GoogleGenerativeAILLMBaseEntity
|
|
25
|
+
from .helpers import convert_to_wav
|
|
28
26
|
|
|
29
27
|
|
|
30
28
|
async def async_setup_entry(
|
|
@@ -32,15 +30,23 @@ async def async_setup_entry(
|
|
|
32
30
|
config_entry: ConfigEntry,
|
|
33
31
|
async_add_entities: AddConfigEntryEntitiesCallback,
|
|
34
32
|
) -> None:
|
|
35
|
-
"""Set up TTS
|
|
36
|
-
|
|
37
|
-
|
|
33
|
+
"""Set up TTS entities."""
|
|
34
|
+
for subentry in config_entry.subentries.values():
|
|
35
|
+
if subentry.subentry_type != "tts":
|
|
36
|
+
continue
|
|
37
|
+
|
|
38
|
+
async_add_entities(
|
|
39
|
+
[GoogleGenerativeAITextToSpeechEntity(config_entry, subentry)],
|
|
40
|
+
config_subentry_id=subentry.subentry_id,
|
|
41
|
+
)
|
|
38
42
|
|
|
39
43
|
|
|
40
|
-
class GoogleGenerativeAITextToSpeechEntity(
|
|
44
|
+
class GoogleGenerativeAITextToSpeechEntity(
|
|
45
|
+
TextToSpeechEntity, GoogleGenerativeAILLMBaseEntity
|
|
46
|
+
):
|
|
41
47
|
"""Google Generative AI text-to-speech entity."""
|
|
42
48
|
|
|
43
|
-
_attr_supported_options = [ATTR_VOICE
|
|
49
|
+
_attr_supported_options = [ATTR_VOICE]
|
|
44
50
|
# See https://ai.google.dev/gemini-api/docs/speech-generation#languages
|
|
45
51
|
_attr_supported_languages = [
|
|
46
52
|
"ar-EG",
|
|
@@ -68,6 +74,8 @@ class GoogleGenerativeAITextToSpeechEntity(TextToSpeechEntity):
|
|
|
68
74
|
"uk-UA",
|
|
69
75
|
"vi-VN",
|
|
70
76
|
]
|
|
77
|
+
# Unused, but required by base class.
|
|
78
|
+
# The Gemini TTS models detect the input language automatically.
|
|
71
79
|
_attr_default_language = "en-US"
|
|
72
80
|
# See https://ai.google.dev/gemini-api/docs/speech-generation#voices
|
|
73
81
|
_supported_voices = [
|
|
@@ -106,110 +114,44 @@ class GoogleGenerativeAITextToSpeechEntity(TextToSpeechEntity):
|
|
|
106
114
|
)
|
|
107
115
|
]
|
|
108
116
|
|
|
109
|
-
def __init__(self,
|
|
110
|
-
"""Initialize
|
|
111
|
-
|
|
112
|
-
self._attr_name = "Google Generative AI TTS"
|
|
113
|
-
self._attr_unique_id = f"{entry.entry_id}_tts"
|
|
114
|
-
self._attr_device_info = dr.DeviceInfo(
|
|
115
|
-
identifiers={(DOMAIN, entry.entry_id)},
|
|
116
|
-
manufacturer="Google",
|
|
117
|
-
model="Generative AI",
|
|
118
|
-
entry_type=dr.DeviceEntryType.SERVICE,
|
|
119
|
-
)
|
|
120
|
-
self._genai_client = entry.runtime_data
|
|
121
|
-
self._default_voice_id = self._supported_voices[0].voice_id
|
|
117
|
+
def __init__(self, config_entry: ConfigEntry, subentry: ConfigSubentry) -> None:
|
|
118
|
+
"""Initialize the TTS entity."""
|
|
119
|
+
super().__init__(config_entry, subentry, RECOMMENDED_TTS_MODEL)
|
|
122
120
|
|
|
123
121
|
@callback
|
|
124
|
-
def async_get_supported_voices(self, language: str) -> list[Voice]
|
|
122
|
+
def async_get_supported_voices(self, language: str) -> list[Voice]:
|
|
125
123
|
"""Return a list of supported voices for a language."""
|
|
126
124
|
return self._supported_voices
|
|
127
125
|
|
|
126
|
+
@cached_property
|
|
127
|
+
def default_options(self) -> Mapping[str, Any]:
|
|
128
|
+
"""Return a mapping with the default options."""
|
|
129
|
+
return {
|
|
130
|
+
ATTR_VOICE: self._supported_voices[0].voice_id,
|
|
131
|
+
}
|
|
132
|
+
|
|
128
133
|
async def async_get_tts_audio(
|
|
129
134
|
self, message: str, language: str, options: dict[str, Any]
|
|
130
135
|
) -> TtsAudioType:
|
|
131
136
|
"""Load tts audio file from the engine."""
|
|
137
|
+
config = self.create_generate_content_config()
|
|
138
|
+
config.response_modalities = ["AUDIO"]
|
|
139
|
+
config.speech_config = types.SpeechConfig(
|
|
140
|
+
voice_config=types.VoiceConfig(
|
|
141
|
+
prebuilt_voice_config=types.PrebuiltVoiceConfig(
|
|
142
|
+
voice_name=options[ATTR_VOICE]
|
|
143
|
+
)
|
|
144
|
+
)
|
|
145
|
+
)
|
|
132
146
|
try:
|
|
133
|
-
response = self._genai_client.models.generate_content(
|
|
134
|
-
model=
|
|
147
|
+
response = await self._genai_client.aio.models.generate_content(
|
|
148
|
+
model=self.subentry.data.get(CONF_CHAT_MODEL, RECOMMENDED_TTS_MODEL),
|
|
135
149
|
contents=message,
|
|
136
|
-
config=
|
|
137
|
-
response_modalities=["AUDIO"],
|
|
138
|
-
speech_config=types.SpeechConfig(
|
|
139
|
-
voice_config=types.VoiceConfig(
|
|
140
|
-
prebuilt_voice_config=types.PrebuiltVoiceConfig(
|
|
141
|
-
voice_name=options.get(
|
|
142
|
-
ATTR_VOICE, self._default_voice_id
|
|
143
|
-
)
|
|
144
|
-
)
|
|
145
|
-
)
|
|
146
|
-
),
|
|
147
|
-
),
|
|
150
|
+
config=config,
|
|
148
151
|
)
|
|
149
|
-
|
|
150
152
|
data = response.candidates[0].content.parts[0].inline_data.data
|
|
151
153
|
mime_type = response.candidates[0].content.parts[0].inline_data.mime_type
|
|
152
|
-
except
|
|
153
|
-
|
|
154
|
-
"Error during processing of TTS request %s", exc, exc_info=True
|
|
155
|
-
)
|
|
154
|
+
except (APIError, ClientError, ValueError) as exc:
|
|
155
|
+
LOGGER.error("Error during TTS: %s", exc, exc_info=True)
|
|
156
156
|
raise HomeAssistantError(exc) from exc
|
|
157
|
-
return "wav",
|
|
158
|
-
|
|
159
|
-
def _convert_to_wav(self, audio_data: bytes, mime_type: str) -> bytes:
|
|
160
|
-
"""Generate a WAV file header for the given audio data and parameters.
|
|
161
|
-
|
|
162
|
-
Args:
|
|
163
|
-
audio_data: The raw audio data as a bytes object.
|
|
164
|
-
mime_type: Mime type of the audio data.
|
|
165
|
-
|
|
166
|
-
Returns:
|
|
167
|
-
A bytes object representing the WAV file header.
|
|
168
|
-
|
|
169
|
-
"""
|
|
170
|
-
parameters = self._parse_audio_mime_type(mime_type)
|
|
171
|
-
|
|
172
|
-
wav_buffer = io.BytesIO()
|
|
173
|
-
with wave.open(wav_buffer, "wb") as wf:
|
|
174
|
-
wf.setnchannels(1)
|
|
175
|
-
wf.setsampwidth(parameters["bits_per_sample"] // 8)
|
|
176
|
-
wf.setframerate(parameters["rate"])
|
|
177
|
-
wf.writeframes(audio_data)
|
|
178
|
-
|
|
179
|
-
return wav_buffer.getvalue()
|
|
180
|
-
|
|
181
|
-
def _parse_audio_mime_type(self, mime_type: str) -> dict[str, int]:
|
|
182
|
-
"""Parse bits per sample and rate from an audio MIME type string.
|
|
183
|
-
|
|
184
|
-
Assumes bits per sample is encoded like "L16" and rate as "rate=xxxxx".
|
|
185
|
-
|
|
186
|
-
Args:
|
|
187
|
-
mime_type: The audio MIME type string (e.g., "audio/L16;rate=24000").
|
|
188
|
-
|
|
189
|
-
Returns:
|
|
190
|
-
A dictionary with "bits_per_sample" and "rate" keys. Values will be
|
|
191
|
-
integers if found, otherwise None.
|
|
192
|
-
|
|
193
|
-
"""
|
|
194
|
-
if not mime_type.startswith("audio/L"):
|
|
195
|
-
_LOGGER.warning("Received unexpected MIME type %s", mime_type)
|
|
196
|
-
raise HomeAssistantError(f"Unsupported audio MIME type: {mime_type}")
|
|
197
|
-
|
|
198
|
-
bits_per_sample = 16
|
|
199
|
-
rate = 24000
|
|
200
|
-
|
|
201
|
-
# Extract rate from parameters
|
|
202
|
-
parts = mime_type.split(";")
|
|
203
|
-
for param in parts: # Skip the main type part
|
|
204
|
-
param = param.strip()
|
|
205
|
-
if param.lower().startswith("rate="):
|
|
206
|
-
# Handle cases like "rate=" with no value or non-integer value and keep rate as default
|
|
207
|
-
with suppress(ValueError, IndexError):
|
|
208
|
-
rate_str = param.split("=", 1)[1]
|
|
209
|
-
rate = int(rate_str)
|
|
210
|
-
elif param.startswith("audio/L"):
|
|
211
|
-
# Keep bits_per_sample as default if conversion fails
|
|
212
|
-
with suppress(ValueError, IndexError):
|
|
213
|
-
bits_per_sample = int(param.split("L", 1)[1])
|
|
214
|
-
|
|
215
|
-
return {"bits_per_sample": bits_per_sample, "rate": rate}
|
|
157
|
+
return "wav", convert_to_wav(data, mime_type)
|
|
@@ -3,12 +3,12 @@
|
|
|
3
3
|
"step": {
|
|
4
4
|
"binary_sensor": {
|
|
5
5
|
"data": {
|
|
6
|
-
"all": "\
|
|
6
|
+
"all": "\u039f\u03bb\u03b5\u03c2 \u03bf\u03b9 \u03bf\u03bd\u03c4\u03cc\u03c4\u03b7\u03c4\u03b5\u03c2",
|
|
7
7
|
"entities": "\u039c\u03ad\u03bb\u03b7",
|
|
8
8
|
"hide_members": "\u0391\u03c0\u03cc\u03ba\u03c1\u03c5\u03c8\u03b7 \u03bc\u03b5\u03bb\u03ce\u03bd",
|
|
9
9
|
"name": "\u039f\u03bd\u03bf\u03bc\u03b1"
|
|
10
10
|
},
|
|
11
|
-
"description": "\u0395\u03ac\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03b7\u03bc\u03ad\u03bd\u03b7 \u03b7 \u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \"\u03cc\u03bb\u03b5\u03c2 \u03bf\u03b9 \u03bf\u03bd\u03c4\u03cc\u03c4\u03b7\u03c4\u03b5\u03c2\", \u03b7 \u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7 \u03c4\u03b7\u03c2 \u03bf\u03bc\u03ac\u03b4\u03b1\u03c2 \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\
|
|
11
|
+
"description": "\u0395\u03ac\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03b7\u03bc\u03ad\u03bd\u03b7 \u03b7 \u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \"\u03cc\u03bb\u03b5\u03c2 \u03bf\u03b9 \u03bf\u03bd\u03c4\u03cc\u03c4\u03b7\u03c4\u03b5\u03c2\", \u03b7 \u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7 \u03c4\u03b7\u03c2 \u03bf\u03bc\u03ac\u03b4\u03b1\u03c2 \u03b5\u03af\u03bd\u03b1\u03b9 \"\u03b5\u03bd\u03b5\u03c1\u03b3\u03cc\" \u03bc\u03cc\u03bd\u03bf \u03b5\u03ac\u03bd \u03cc\u03bb\u03b1 \u03c4\u03b1 \u03bc\u03ad\u03bb\u03b7 \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03b7\u03bc\u03ad\u03bd\u03b1. \u0395\u03ac\u03bd \u03b7 \u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \"\u03cc\u03bb\u03b5\u03c2 \u03bf\u03b9 \u03bf\u03bd\u03c4\u03cc\u03c4\u03b7\u03c4\u03b5\u03c2\" \u03b5\u03af\u03bd\u03b1\u03b9 \u03b1\u03c0\u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03b7\u03bc\u03ad\u03bd\u03b7, \u03b7 \u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7 \u03c4\u03b7\u03c2 \u03bf\u03bc\u03ac\u03b4\u03b1\u03c2 \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03b7\u03bc\u03ad\u03bd\u03b7 \u03b5\u03ac\u03bd \u03bf\u03c0\u03bf\u03b9\u03bf\u03b4\u03ae\u03c0\u03bf\u03c4\u03b5 \u03bc\u03ad\u03bb\u03bf\u03c2 \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03b7\u03bc\u03ad\u03bd\u03bf.",
|
|
12
12
|
"title": "\u0394\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03af\u03b1 \u03bf\u03bc\u03ac\u03b4\u03b1\u03c2"
|
|
13
13
|
},
|
|
14
14
|
"button": {
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"hide_members": "\u0391\u03c0\u03cc\u03ba\u03c1\u03c5\u03c8\u03b7 \u03bc\u03b5\u03bb\u03ce\u03bd",
|
|
83
83
|
"ignore_non_numeric": "\u03a0\u03b1\u03c1\u03ac\u03b2\u03bb\u03b5\u03c8\u03b7 \u03bc\u03b7 \u03b1\u03c1\u03b9\u03b8\u03bc\u03b7\u03c4\u03b9\u03ba\u03ce\u03bd",
|
|
84
84
|
"name": "\u039f\u03bd\u03bf\u03bc\u03b1",
|
|
85
|
-
"round_digits": "\u03a3\u03c4\u03c1\u03bf\u03b3\u03b3\u03c5\u03bb\u03bf\u03c0\u03bf\
|
|
85
|
+
"round_digits": "\u03a3\u03c4\u03c1\u03bf\u03b3\u03b3\u03c5\u03bb\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b7 \u03c4\u03b7\u03c2 \u03c4\u03b9\u03bc\u03ae\u03c2 \u03c3\u03b5 \u03b1\u03c1\u03b9\u03b8\u03bc\u03cc \u03b4\u03b5\u03ba\u03b1\u03b4\u03b9\u03ba\u03ce\u03bd \u03c8\u03b7\u03c6\u03af\u03c9\u03bd",
|
|
86
86
|
"state_class": "\u039a\u03bb\u03ac\u03c3\u03b7 \u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7\u03c2",
|
|
87
87
|
"type": "\u03a4\u03cd\u03c0\u03bf\u03c2",
|
|
88
88
|
"unit_of_measurement": "\u039c\u03bf\u03bd\u03ac\u03b4\u03b1 \u03bc\u03ad\u03c4\u03c1\u03b7\u03c3\u03b7\u03c2"
|
|
@@ -106,9 +106,9 @@
|
|
|
106
106
|
"event": "\u039f\u03bc\u03ac\u03b4\u03b1 \u03c3\u03c5\u03bc\u03b2\u03ac\u03bd\u03c4\u03c9\u03bd",
|
|
107
107
|
"fan": "\u039f\u03bc\u03ac\u03b4\u03b1 \u03b1\u03bd\u03b5\u03bc\u03b9\u03c3\u03c4\u03ae\u03c1\u03c9\u03bd",
|
|
108
108
|
"light": "\u039f\u03bc\u03ac\u03b4\u03b1 \u03c6\u03ce\u03c4\u03c9\u03bd",
|
|
109
|
-
"lock": "\u039f\u03bc\u03ac\u03b4\u03b1 \u03ba\u03bb\u03b5\u03b9\u03b4\
|
|
110
|
-
"media_player": "\u039f\u03bc\u03ac\u03b4\u03b1 \u03b1\u03bd\u03b1\u03c0\u03b1\u03c1\u03b1\u03b3\u03c9\u03b3\u03ae\u03c2 \u03c0\u03bf\u03bb\u03c5\u03bc\u03ad\u03c3\u03c9\u03bd",
|
|
111
|
-
"notify": "\
|
|
109
|
+
"lock": "\u039f\u03bc\u03ac\u03b4\u03b1 \u03ba\u03bb\u03b5\u03b9\u03b4\u03b1\u03c1\u03b9\u03ce\u03bd",
|
|
110
|
+
"media_player": "\u039f\u03bc\u03ac\u03b4\u03b1 \u03c3\u03c5\u03c3\u03ba\u03b5\u03c5\u03ce\u03bd \u03b1\u03bd\u03b1\u03c0\u03b1\u03c1\u03b1\u03b3\u03c9\u03b3\u03ae\u03c2 \u03c0\u03bf\u03bb\u03c5\u03bc\u03ad\u03c3\u03c9\u03bd",
|
|
111
|
+
"notify": "\u039f\u03bc\u03ac\u03b4\u03b1 \u03b5\u03b9\u03b4\u03bf\u03c0\u03bf\u03b9\u03ae\u03c3\u03b5\u03c9\u03bd",
|
|
112
112
|
"sensor": "\u039f\u03bc\u03ac\u03b4\u03b1 \u03b1\u03b9\u03c3\u03b8\u03b7\u03c4\u03ae\u03c1\u03c9\u03bd",
|
|
113
113
|
"switch": "\u039f\u03bc\u03ac\u03b4\u03b1 \u03b4\u03b9\u03b1\u03ba\u03bf\u03c0\u03c4\u03ce\u03bd"
|
|
114
114
|
},
|
|
@@ -160,11 +160,11 @@
|
|
|
160
160
|
"step": {
|
|
161
161
|
"binary_sensor": {
|
|
162
162
|
"data": {
|
|
163
|
-
"all": "\
|
|
163
|
+
"all": "\u039f\u03bb\u03b5\u03c2 \u03bf\u03b9 \u03bf\u03bd\u03c4\u03cc\u03c4\u03b7\u03c4\u03b5\u03c2",
|
|
164
164
|
"entities": "\u039c\u03ad\u03bb\u03b7",
|
|
165
165
|
"hide_members": "\u0391\u03c0\u03cc\u03ba\u03c1\u03c5\u03c8\u03b7 \u03bc\u03b5\u03bb\u03ce\u03bd"
|
|
166
166
|
},
|
|
167
|
-
"description": "\u0395\u03ac\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03b7\u03bc\u03ad\u03bd\u03b7 \u03b7 \u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \"\u03cc\u03bb\u03b5\u03c2 \u03bf\u03b9 \u03bf\u03bd\u03c4\u03cc\u03c4\u03b7\u03c4\u03b5\u03c2\", \u03b7 \u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7 \u03c4\u03b7\u03c2 \u03bf\u03bc\u03ac\u03b4\u03b1\u03c2 \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\
|
|
167
|
+
"description": "\u0395\u03ac\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03b7\u03bc\u03ad\u03bd\u03b7 \u03b7 \u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \"\u03cc\u03bb\u03b5\u03c2 \u03bf\u03b9 \u03bf\u03bd\u03c4\u03cc\u03c4\u03b7\u03c4\u03b5\u03c2\", \u03b7 \u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7 \u03c4\u03b7\u03c2 \u03bf\u03bc\u03ac\u03b4\u03b1\u03c2 \u03b5\u03af\u03bd\u03b1\u03b9 \"\u03b5\u03bd\u03b5\u03c1\u03b3\u03cc\" \u03bc\u03cc\u03bd\u03bf \u03b5\u03ac\u03bd \u03cc\u03bb\u03b1 \u03c4\u03b1 \u03bc\u03ad\u03bb\u03b7 \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03b7\u03bc\u03ad\u03bd\u03b1. \u0395\u03ac\u03bd \u03b7 \u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \"\u03cc\u03bb\u03b5\u03c2 \u03bf\u03b9 \u03bf\u03bd\u03c4\u03cc\u03c4\u03b7\u03c4\u03b5\u03c2\" \u03b5\u03af\u03bd\u03b1\u03b9 \u03b1\u03c0\u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03b7\u03bc\u03ad\u03bd\u03b7, \u03b7 \u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7 \u03c4\u03b7\u03c2 \u03bf\u03bc\u03ac\u03b4\u03b1\u03c2 \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03b7\u03bc\u03ad\u03bd\u03b7 \u03b5\u03ac\u03bd \u03bf\u03c0\u03bf\u03b9\u03bf\u03b4\u03ae\u03c0\u03bf\u03c4\u03b5 \u03bc\u03ad\u03bb\u03bf\u03c2 \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03b7\u03bc\u03ad\u03bd\u03bf."
|
|
168
168
|
},
|
|
169
169
|
"button": {
|
|
170
170
|
"data": {
|
|
@@ -186,11 +186,11 @@
|
|
|
186
186
|
},
|
|
187
187
|
"light": {
|
|
188
188
|
"data": {
|
|
189
|
-
"all": "\
|
|
189
|
+
"all": "\u039f\u03bb\u03b5\u03c2 \u03bf\u03b9 \u03bf\u03bd\u03c4\u03cc\u03c4\u03b7\u03c4\u03b5\u03c2",
|
|
190
190
|
"entities": "\u039c\u03ad\u03bb\u03b7",
|
|
191
191
|
"hide_members": "\u0391\u03c0\u03cc\u03ba\u03c1\u03c5\u03c8\u03b7 \u03bc\u03b5\u03bb\u03ce\u03bd"
|
|
192
192
|
},
|
|
193
|
-
"description": "\u0395\u03ac\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03b7\u03bc\u03ad\u03bd\u03b7 \u03b7 \u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \"\u03cc\u03bb\u03b5\u03c2 \u03bf\u03b9 \u03bf\u03bd\u03c4\u03cc\u03c4\u03b7\u03c4\u03b5\u03c2\", \u03b7 \u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7 \u03c4\u03b7\u03c2 \u03bf\u03bc\u03ac\u03b4\u03b1\u03c2 \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\
|
|
193
|
+
"description": "\u0395\u03ac\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03b7\u03bc\u03ad\u03bd\u03b7 \u03b7 \u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \"\u03cc\u03bb\u03b5\u03c2 \u03bf\u03b9 \u03bf\u03bd\u03c4\u03cc\u03c4\u03b7\u03c4\u03b5\u03c2\", \u03b7 \u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7 \u03c4\u03b7\u03c2 \u03bf\u03bc\u03ac\u03b4\u03b1\u03c2 \u03b5\u03af\u03bd\u03b1\u03b9 \"\u03b5\u03bd\u03b5\u03c1\u03b3\u03cc\" \u03bc\u03cc\u03bd\u03bf \u03b5\u03ac\u03bd \u03cc\u03bb\u03b1 \u03c4\u03b1 \u03bc\u03ad\u03bb\u03b7 \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03b7\u03bc\u03ad\u03bd\u03b1. \u0395\u03ac\u03bd \u03b7 \u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \"\u03cc\u03bb\u03b5\u03c2 \u03bf\u03b9 \u03bf\u03bd\u03c4\u03cc\u03c4\u03b7\u03c4\u03b5\u03c2\" \u03b5\u03af\u03bd\u03b1\u03b9 \u03b1\u03c0\u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03b7\u03bc\u03ad\u03bd\u03b7, \u03b7 \u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7 \u03c4\u03b7\u03c2 \u03bf\u03bc\u03ac\u03b4\u03b1\u03c2 \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03b7\u03bc\u03ad\u03bd\u03b7 \u03b5\u03ac\u03bd \u03bf\u03c0\u03bf\u03b9\u03bf\u03b4\u03ae\u03c0\u03bf\u03c4\u03b5 \u03bc\u03ad\u03bb\u03bf\u03c2 \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03b7\u03bc\u03ad\u03bd\u03bf."
|
|
194
194
|
},
|
|
195
195
|
"lock": {
|
|
196
196
|
"data": {
|
|
@@ -216,7 +216,7 @@
|
|
|
216
216
|
"entities": "\u039c\u03ad\u03bb\u03b7",
|
|
217
217
|
"hide_members": "\u0391\u03c0\u03cc\u03ba\u03c1\u03c5\u03c8\u03b7 \u03bc\u03b5\u03bb\u03ce\u03bd",
|
|
218
218
|
"ignore_non_numeric": "\u03a0\u03b1\u03c1\u03ac\u03b2\u03bb\u03b5\u03c8\u03b7 \u03bc\u03b7 \u03b1\u03c1\u03b9\u03b8\u03bc\u03b7\u03c4\u03b9\u03ba\u03ce\u03bd",
|
|
219
|
-
"round_digits": "\u03a3\u03c4\u03c1\u03bf\u03b3\u03b3\u03c5\u03bb\u03bf\u03c0\u03bf\
|
|
219
|
+
"round_digits": "\u03a3\u03c4\u03c1\u03bf\u03b3\u03b3\u03c5\u03bb\u03bf\u03c0\u03bf\u03af\u03b7\u03c3\u03b7 \u03c4\u03b7\u03c2 \u03c4\u03b9\u03bc\u03ae\u03c2 \u03c3\u03b5 \u03b1\u03c1\u03b9\u03b8\u03bc\u03cc \u03b4\u03b5\u03ba\u03b1\u03b4\u03b9\u03ba\u03ce\u03bd \u03c8\u03b7\u03c6\u03af\u03c9\u03bd",
|
|
220
220
|
"state_class": "\u039a\u03bb\u03ac\u03c3\u03b7 \u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7\u03c2",
|
|
221
221
|
"type": "\u03a4\u03cd\u03c0\u03bf\u03c2",
|
|
222
222
|
"unit_of_measurement": "\u039c\u03bf\u03bd\u03ac\u03b4\u03b1 \u03bc\u03ad\u03c4\u03c1\u03b7\u03c3\u03b7\u03c2"
|
|
@@ -225,11 +225,11 @@
|
|
|
225
225
|
},
|
|
226
226
|
"switch": {
|
|
227
227
|
"data": {
|
|
228
|
-
"all": "\
|
|
228
|
+
"all": "\u039f\u03bb\u03b5\u03c2 \u03bf\u03b9 \u03bf\u03bd\u03c4\u03cc\u03c4\u03b7\u03c4\u03b5\u03c2",
|
|
229
229
|
"entities": "\u039c\u03ad\u03bb\u03b7",
|
|
230
230
|
"hide_members": "\u0391\u03c0\u03cc\u03ba\u03c1\u03c5\u03c8\u03b7 \u03bc\u03b5\u03bb\u03ce\u03bd"
|
|
231
231
|
},
|
|
232
|
-
"description": "\u0395\u03ac\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03b7\u03bc\u03ad\u03bd\u03b7 \u03b7 \u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \"\u03cc\u03bb\u03b5\u03c2 \u03bf\u03b9 \u03bf\u03bd\u03c4\u03cc\u03c4\u03b7\u03c4\u03b5\u03c2\", \u03b7 \u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7 \u03c4\u03b7\u03c2 \u03bf\u03bc\u03ac\u03b4\u03b1\u03c2 \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\
|
|
232
|
+
"description": "\u0395\u03ac\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03b7\u03bc\u03ad\u03bd\u03b7 \u03b7 \u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \"\u03cc\u03bb\u03b5\u03c2 \u03bf\u03b9 \u03bf\u03bd\u03c4\u03cc\u03c4\u03b7\u03c4\u03b5\u03c2\", \u03b7 \u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7 \u03c4\u03b7\u03c2 \u03bf\u03bc\u03ac\u03b4\u03b1\u03c2 \u03b5\u03af\u03bd\u03b1\u03b9 \"\u03b5\u03bd\u03b5\u03c1\u03b3\u03cc\" \u03bc\u03cc\u03bd\u03bf \u03b5\u03ac\u03bd \u03cc\u03bb\u03b1 \u03c4\u03b1 \u03bc\u03ad\u03bb\u03b7 \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03b7\u03bc\u03ad\u03bd\u03b1. \u0395\u03ac\u03bd \u03b7 \u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \"\u03cc\u03bb\u03b5\u03c2 \u03bf\u03b9 \u03bf\u03bd\u03c4\u03cc\u03c4\u03b7\u03c4\u03b5\u03c2\" \u03b5\u03af\u03bd\u03b1\u03b9 \u03b1\u03c0\u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03b7\u03bc\u03ad\u03bd\u03b7, \u03b7 \u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7 \u03c4\u03b7\u03c2 \u03bf\u03bc\u03ac\u03b4\u03b1\u03c2 \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03b7\u03bc\u03ad\u03bd\u03b7 \u03b5\u03ac\u03bd \u03bf\u03c0\u03bf\u03b9\u03bf\u03b4\u03ae\u03c0\u03bf\u03c4\u03b5 \u03bc\u03ad\u03bb\u03bf\u03c2 \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03bd\u03b5\u03c1\u03b3\u03bf\u03c0\u03bf\u03b9\u03b7\u03bc\u03ad\u03bd\u03bf."
|
|
233
233
|
}
|
|
234
234
|
}
|
|
235
235
|
},
|
|
@@ -242,9 +242,9 @@
|
|
|
242
242
|
"median": "\u0394\u03b9\u03ac\u03bc\u03b5\u03c3\u03bf\u03c2",
|
|
243
243
|
"min": "\u0395\u03bb\u03ac\u03c7\u03b9\u03c3\u03c4\u03bf",
|
|
244
244
|
"product": "\u03a0\u03c1\u03bf\u03ca\u03cc\u03bd",
|
|
245
|
-
"range": "\
|
|
245
|
+
"range": "\u0395\u03cd\u03c1\u03bf\u03c2 \u03c3\u03c4\u03b1\u03c4\u03b9\u03c3\u03c4\u03b9\u03ba\u03ce\u03bd",
|
|
246
246
|
"stdev": "\u03a4\u03c5\u03c0\u03b9\u03ba\u03ae \u03b1\u03c0\u03cc\u03ba\u03bb\u03b9\u03c3\u03b7",
|
|
247
|
-
"sum": "\
|
|
247
|
+
"sum": "\u0391\u03b8\u03c1\u03bf\u03b9\u03c3\u03bc\u03b1"
|
|
248
248
|
}
|
|
249
249
|
}
|
|
250
250
|
},
|
|
@@ -267,7 +267,7 @@
|
|
|
267
267
|
"description": "\u0394\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03b5\u03af/\u0395\u03bd\u03b7\u03bc\u03b5\u03c1\u03ce\u03bd\u03b5\u03b9 \u03bc\u03b9\u03b1 \u03bf\u03bc\u03ac\u03b4\u03b1.",
|
|
268
268
|
"fields": {
|
|
269
269
|
"add_entities": {
|
|
270
|
-
"description": "\u039b\u03af\u03c3\u03c4\u03b1 \u03c4\u03c9\u03bd \u03bc\u03b5\u03bb\u03ce\u03bd \u03c0\u03bf\u03c5 \u03c0\u03c1\u03ad\u03c0\u03b5\u03b9 \u03bd\u03b1 \u03c0\u03c1\u03bf\u03c3\u03c4\u03b5\u03b8\u03bf\u03cd\u03bd \u03c3\u03c4\u03b7\u03bd \u03bf\u03bc\u03ac\u03b4\u03b1. \u0394\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03b5\u03af \u03bd\u03b1 \u03c7\u03c1\u03b7\u03c3\u03b9\u03bc\u03bf\u03c0\u03bf\u03b9\u03b7\u03b8\u03b5\u03af \u03c3\u03b5 \u03c3\u03c5\u03bd\u03b4\u03c5\u03b1\u03c3\u03bc\u03cc \u03bc\u03b5 \u03c4\u03b9\u03c2 \u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ad\u03c2 `
|
|
270
|
+
"description": "\u039b\u03af\u03c3\u03c4\u03b1 \u03c4\u03c9\u03bd \u03bc\u03b5\u03bb\u03ce\u03bd \u03c0\u03bf\u03c5 \u03c0\u03c1\u03ad\u03c0\u03b5\u03b9 \u03bd\u03b1 \u03c0\u03c1\u03bf\u03c3\u03c4\u03b5\u03b8\u03bf\u03cd\u03bd \u03c3\u03c4\u03b7\u03bd \u03bf\u03bc\u03ac\u03b4\u03b1. \u0394\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03b5\u03af \u03bd\u03b1 \u03c7\u03c1\u03b7\u03c3\u03b9\u03bc\u03bf\u03c0\u03bf\u03b9\u03b7\u03b8\u03b5\u03af \u03c3\u03b5 \u03c3\u03c5\u03bd\u03b4\u03c5\u03b1\u03c3\u03bc\u03cc \u03bc\u03b5 \u03c4\u03b9\u03c2 \u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ad\u03c2 `\u039f\u03bd\u03c4\u03cc\u03c4\u03b7\u03c4\u03b5\u03c2` \u03ae `\u0391\u03c6\u03b1\u03af\u03c1\u03b5\u03c3\u03b7 \u03bf\u03bd\u03c4\u03bf\u03c4\u03ae\u03c4\u03c9\u03bd`.",
|
|
271
271
|
"name": "\u03a0\u03c1\u03bf\u03c3\u03b8\u03ae\u03ba\u03b7 \u03bf\u03bd\u03c4\u03bf\u03c4\u03ae\u03c4\u03c9\u03bd"
|
|
272
272
|
},
|
|
273
273
|
"all": {
|
|
@@ -275,7 +275,7 @@
|
|
|
275
275
|
"name": "\u039f\u03bb\u03b1"
|
|
276
276
|
},
|
|
277
277
|
"entities": {
|
|
278
|
-
"description": "\u039b\u03af\u03c3\u03c4\u03b1 \u03cc\u03bb\u03c9\u03bd \u03c4\u03c9\u03bd \u03bc\u03b5\u03bb\u03ce\u03bd \u03c4\u03b7\u03c2 \u03bf\u03bc\u03ac\u03b4\u03b1\u03c2. \u0394\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03b5\u03af \u03bd\u03b1 \u03c7\u03c1\u03b7\u03c3\u03b9\u03bc\u03bf\u03c0\u03bf\u03b9\u03b7\u03b8\u03b5\u03af \u03c3\u03b5 \u03c3\u03c5\u03bd\u03b4\u03c5\u03b1\u03c3\u03bc\u03cc \u03bc\u03b5 \u03c4\u03b9\u03c2 \u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ad\u03c2
|
|
278
|
+
"description": "\u039b\u03af\u03c3\u03c4\u03b1 \u03cc\u03bb\u03c9\u03bd \u03c4\u03c9\u03bd \u03bc\u03b5\u03bb\u03ce\u03bd \u03c4\u03b7\u03c2 \u03bf\u03bc\u03ac\u03b4\u03b1\u03c2. \u0394\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03b5\u03af \u03bd\u03b1 \u03c7\u03c1\u03b7\u03c3\u03b9\u03bc\u03bf\u03c0\u03bf\u03b9\u03b7\u03b8\u03b5\u03af \u03c3\u03b5 \u03c3\u03c5\u03bd\u03b4\u03c5\u03b1\u03c3\u03bc\u03cc \u03bc\u03b5 \u03c4\u03b9\u03c2 \u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ad\u03c2 `\u03a0\u03c1\u03bf\u03c3\u03b8\u03ae\u03ba\u03b7 \u03bf\u03bd\u03c4\u03bf\u03c4\u03ae\u03c4\u03c9\u03bd` \u03ae `\u0391\u03c6\u03b1\u03af\u03c1\u03b5\u03c3\u03b7 \u03bf\u03bd\u03c4\u03bf\u03c4\u03ae\u03c4\u03c9\u03bd`.",
|
|
279
279
|
"name": "\u039f\u03bd\u03c4\u03cc\u03c4\u03b7\u03c4\u03b5\u03c2"
|
|
280
280
|
},
|
|
281
281
|
"icon": {
|
|
@@ -291,7 +291,7 @@
|
|
|
291
291
|
"name": "ID \u03b1\u03bd\u03c4\u03b9\u03ba\u03b5\u03b9\u03bc\u03ad\u03bd\u03bf\u03c5"
|
|
292
292
|
},
|
|
293
293
|
"remove_entities": {
|
|
294
|
-
"description": "\u039b\u03af\u03c3\u03c4\u03b1 \u03c4\u03c9\u03bd \u03bc\u03b5\u03bb\u03ce\u03bd \u03c0\u03bf\u03c5 \u03c0\u03c1\u03ad\u03c0\u03b5\u03b9 \u03bd\u03b1 \u03b1\u03c6\u03b1\u03b9\u03c1\u03b5\u03b8\u03bf\u03cd\u03bd \u03b1\u03c0\u03cc \u03bc\u03b9\u03b1 \u03bf\u03bc\u03ac\u03b4\u03b1. \u0394\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03b5\u03af \u03bd\u03b1 \u03c7\u03c1\u03b7\u03c3\u03b9\u03bc\u03bf\u03c0\u03bf\u03b9\u03b7\u03b8\u03b5\u03af \u03c3\u03b5 \u03c3\u03c5\u03bd\u03b4\u03c5\u03b1\u03c3\u03bc\u03cc \u03bc\u03b5 \u03c4\u03b9\u03c2 \u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ad\u03c2 `
|
|
294
|
+
"description": "\u039b\u03af\u03c3\u03c4\u03b1 \u03c4\u03c9\u03bd \u03bc\u03b5\u03bb\u03ce\u03bd \u03c0\u03bf\u03c5 \u03c0\u03c1\u03ad\u03c0\u03b5\u03b9 \u03bd\u03b1 \u03b1\u03c6\u03b1\u03b9\u03c1\u03b5\u03b8\u03bf\u03cd\u03bd \u03b1\u03c0\u03cc \u03bc\u03b9\u03b1 \u03bf\u03bc\u03ac\u03b4\u03b1. \u0394\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03b5\u03af \u03bd\u03b1 \u03c7\u03c1\u03b7\u03c3\u03b9\u03bc\u03bf\u03c0\u03bf\u03b9\u03b7\u03b8\u03b5\u03af \u03c3\u03b5 \u03c3\u03c5\u03bd\u03b4\u03c5\u03b1\u03c3\u03bc\u03cc \u03bc\u03b5 \u03c4\u03b9\u03c2 \u03b5\u03c0\u03b9\u03bb\u03bf\u03b3\u03ad\u03c2 `\u039f\u03bd\u03c4\u03cc\u03c4\u03b7\u03c4\u03b5\u03c2` \u03ae `\u03a0\u03c1\u03bf\u03c3\u03b8\u03ae\u03ba\u03b7 \u03bf\u03bd\u03c4\u03bf\u03c4\u03ae\u03c4\u03c9\u03bd`.",
|
|
295
295
|
"name": "\u0391\u03c6\u03b1\u03af\u03c1\u03b5\u03c3\u03b7 \u03bf\u03bd\u03c4\u03bf\u03c4\u03ae\u03c4\u03c9\u03bd"
|
|
296
296
|
}
|
|
297
297
|
},
|
|
@@ -9,7 +9,7 @@ ASSETS_URL = "https://habitica-assets.s3.amazonaws.com/mobileApp/images/"
|
|
|
9
9
|
SITE_DATA_URL = "https://habitica.com/user/settings/siteData"
|
|
10
10
|
FORGOT_PASSWORD_URL = "https://habitica.com/forgot-password"
|
|
11
11
|
SIGN_UP_URL = "https://habitica.com/register"
|
|
12
|
-
HABITICANS_URL = "https://habitica.com/
|
|
12
|
+
HABITICANS_URL = "https://cdn.habitica.com/assets/home-main@3x-Dwnue45Z.png"
|
|
13
13
|
|
|
14
14
|
DOMAIN = "habitica"
|
|
15
15
|
|
|
@@ -7,7 +7,10 @@ import asyncio
|
|
|
7
7
|
import logging
|
|
8
8
|
from typing import Any
|
|
9
9
|
|
|
10
|
-
from
|
|
10
|
+
from aiohttp import ClientError
|
|
11
|
+
from ha_silabs_firmware_client import FirmwareUpdateClient, ManifestMissing
|
|
12
|
+
from universal_silabs_flasher.common import Version
|
|
13
|
+
from universal_silabs_flasher.firmware import NabuCasaMetadata
|
|
11
14
|
|
|
12
15
|
from homeassistant.components.hassio import (
|
|
13
16
|
AddonError,
|
|
@@ -149,15 +152,78 @@ class BaseFirmwareInstallFlow(ConfigEntryBaseFlow, ABC):
|
|
|
149
152
|
assert self._device is not None
|
|
150
153
|
|
|
151
154
|
if not self.firmware_install_task:
|
|
155
|
+
# We 100% need to install new firmware only if the wrong firmware is
|
|
156
|
+
# currently installed
|
|
157
|
+
firmware_install_required = self._probed_firmware_info is None or (
|
|
158
|
+
self._probed_firmware_info.firmware_type
|
|
159
|
+
!= expected_installed_firmware_type
|
|
160
|
+
)
|
|
161
|
+
|
|
152
162
|
session = async_get_clientsession(self.hass)
|
|
153
163
|
client = FirmwareUpdateClient(fw_update_url, session)
|
|
154
|
-
manifest = await client.async_update_data()
|
|
155
164
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
165
|
+
try:
|
|
166
|
+
manifest = await client.async_update_data()
|
|
167
|
+
fw_manifest = next(
|
|
168
|
+
fw for fw in manifest.firmwares if fw.filename.startswith(fw_type)
|
|
169
|
+
)
|
|
170
|
+
except (StopIteration, TimeoutError, ClientError, ManifestMissing) as err:
|
|
171
|
+
_LOGGER.warning(
|
|
172
|
+
"Failed to fetch firmware update manifest", exc_info=True
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
# Not having internet access should not prevent setup
|
|
176
|
+
if not firmware_install_required:
|
|
177
|
+
_LOGGER.debug(
|
|
178
|
+
"Skipping firmware upgrade due to index download failure"
|
|
179
|
+
)
|
|
180
|
+
return self.async_show_progress_done(next_step_id=next_step_id)
|
|
181
|
+
|
|
182
|
+
raise AbortFlow(
|
|
183
|
+
"fw_download_failed",
|
|
184
|
+
description_placeholders={
|
|
185
|
+
**self._get_translation_placeholders(),
|
|
186
|
+
"firmware_name": firmware_name,
|
|
187
|
+
},
|
|
188
|
+
) from err
|
|
189
|
+
|
|
190
|
+
if not firmware_install_required:
|
|
191
|
+
assert self._probed_firmware_info is not None
|
|
192
|
+
|
|
193
|
+
# Make sure we do not downgrade the firmware
|
|
194
|
+
fw_metadata = NabuCasaMetadata.from_json(fw_manifest.metadata)
|
|
195
|
+
fw_version = fw_metadata.get_public_version()
|
|
196
|
+
probed_fw_version = Version(self._probed_firmware_info.firmware_version)
|
|
197
|
+
|
|
198
|
+
if probed_fw_version >= fw_version:
|
|
199
|
+
_LOGGER.debug(
|
|
200
|
+
"Not downgrading firmware, installed %s is newer than available %s",
|
|
201
|
+
probed_fw_version,
|
|
202
|
+
fw_version,
|
|
203
|
+
)
|
|
204
|
+
return self.async_show_progress_done(next_step_id=next_step_id)
|
|
205
|
+
|
|
206
|
+
try:
|
|
207
|
+
fw_data = await client.async_fetch_firmware(fw_manifest)
|
|
208
|
+
except (TimeoutError, ClientError, ValueError) as err:
|
|
209
|
+
_LOGGER.warning("Failed to fetch firmware update", exc_info=True)
|
|
210
|
+
|
|
211
|
+
# If we cannot download new firmware, we shouldn't block setup
|
|
212
|
+
if not firmware_install_required:
|
|
213
|
+
_LOGGER.debug(
|
|
214
|
+
"Skipping firmware upgrade due to image download failure"
|
|
215
|
+
)
|
|
216
|
+
return self.async_show_progress_done(next_step_id=next_step_id)
|
|
217
|
+
|
|
218
|
+
# Otherwise, fail
|
|
219
|
+
raise AbortFlow(
|
|
220
|
+
"fw_download_failed",
|
|
221
|
+
description_placeholders={
|
|
222
|
+
**self._get_translation_placeholders(),
|
|
223
|
+
"firmware_name": firmware_name,
|
|
224
|
+
},
|
|
225
|
+
) from err
|
|
159
226
|
|
|
160
|
-
fw_data = await client.async_fetch_firmware(fw_meta)
|
|
161
227
|
self.firmware_install_task = self.hass.async_create_task(
|
|
162
228
|
async_flash_silabs_firmware(
|
|
163
229
|
hass=self.hass,
|
|
@@ -215,6 +281,14 @@ class BaseFirmwareInstallFlow(ConfigEntryBaseFlow, ABC):
|
|
|
215
281
|
},
|
|
216
282
|
)
|
|
217
283
|
|
|
284
|
+
async def async_step_pre_confirm_zigbee(
|
|
285
|
+
self, user_input: dict[str, Any] | None = None
|
|
286
|
+
) -> ConfigFlowResult:
|
|
287
|
+
"""Pre-confirm Zigbee setup."""
|
|
288
|
+
|
|
289
|
+
# This step is necessary to prevent `user_input` from being passed through
|
|
290
|
+
return await self.async_step_confirm_zigbee()
|
|
291
|
+
|
|
218
292
|
async def async_step_confirm_zigbee(
|
|
219
293
|
self, user_input: dict[str, Any] | None = None
|
|
220
294
|
) -> ConfigFlowResult:
|
|
@@ -409,7 +483,15 @@ class BaseFirmwareInstallFlow(ConfigEntryBaseFlow, ABC):
|
|
|
409
483
|
finally:
|
|
410
484
|
self.addon_start_task = None
|
|
411
485
|
|
|
412
|
-
return self.async_show_progress_done(next_step_id="
|
|
486
|
+
return self.async_show_progress_done(next_step_id="pre_confirm_otbr")
|
|
487
|
+
|
|
488
|
+
async def async_step_pre_confirm_otbr(
|
|
489
|
+
self, user_input: dict[str, Any] | None = None
|
|
490
|
+
) -> ConfigFlowResult:
|
|
491
|
+
"""Pre-confirm OTBR setup."""
|
|
492
|
+
|
|
493
|
+
# This step is necessary to prevent `user_input` from being passed through
|
|
494
|
+
return await self.async_step_confirm_otbr()
|
|
413
495
|
|
|
414
496
|
async def async_step_confirm_otbr(
|
|
415
497
|
self, user_input: dict[str, Any] | None = None
|
|
@@ -36,7 +36,8 @@
|
|
|
36
36
|
"otbr_addon_already_running": "The OpenThread Border Router add-on is already running, it cannot be installed again.",
|
|
37
37
|
"zha_still_using_stick": "This {model} is in use by the Zigbee Home Automation integration. Please migrate your Zigbee network to another adapter or delete the integration and try again.",
|
|
38
38
|
"otbr_still_using_stick": "This {model} is in use by the OpenThread Border Router add-on. If you use the Thread network, make sure you have alternative border routers. Uninstall the add-on and try again.",
|
|
39
|
-
"unsupported_firmware": "The radio firmware on your {model} could not be determined. Make sure that no other integration or add-on is currently trying to communicate with the device. If you are running Home Assistant OS in a virtual machine or in Docker, please make sure that permissions are set correctly for the device."
|
|
39
|
+
"unsupported_firmware": "The radio firmware on your {model} could not be determined. Make sure that no other integration or add-on is currently trying to communicate with the device. If you are running Home Assistant OS in a virtual machine or in Docker, please make sure that permissions are set correctly for the device.",
|
|
40
|
+
"fw_download_failed": "{firmware_name} firmware for your {model} failed to download. Make sure Home Assistant has internet access and try again."
|
|
40
41
|
},
|
|
41
42
|
"progress": {
|
|
42
43
|
"install_firmware": "Please wait while {firmware_name} firmware is installed to your {model}, this will take a few minutes. Do not make any changes to your hardware or software until this finishes."
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
"firmware_picker": {
|
|
3
3
|
"options": {
|
|
4
4
|
"abort": {
|
|
5
|
+
"fw_download_failed": "Download der {firmware_name}-Firmware f\u00fcr deinen {model} fehlgeschlagen. Stelle sicher, dass Home Assistant einen Internetzugang hat und versuche es erneut.",
|
|
5
6
|
"not_hassio_thread": "Das OpenThread Border Router-Add-on kann nur mit Home Assistant OS installiert werden. Wenn du das {model} als Thread Border Router verwenden m\u00f6chtest, flashe die Firmware bitte manuell mit dem [Web Flasher]({docs_web_flasher_url}) und richte den OpenThread Border Router f\u00fcr die Kommunikation damit ein.",
|
|
6
7
|
"otbr_addon_already_running": "Das OpenThread Border Router-Add-on wird bereits ausgef\u00fchrt und kann nicht erneut installiert werden.",
|
|
7
8
|
"otbr_still_using_stick": "Dieses {model} wird vom OpenThread Border Router-Add-on verwendet. Wenn du das Thread-Netzwerk verwendest, stelle sicher, dass du alternative Border-Router hast. Deinstalliere das Add-on und versuche es erneut.",
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
"firmware_picker": {
|
|
3
3
|
"options": {
|
|
4
4
|
"abort": {
|
|
5
|
+
"fw_download_failed": "{firmware_name} firmware for your {model} failed to download. Make sure Home Assistant has internet access and try again.",
|
|
5
6
|
"not_hassio_thread": "The OpenThread Border Router add-on can only be installed with Home Assistant OS. If you would like to use the {model} as a Thread border router, please flash the firmware manually using the [web flasher]({docs_web_flasher_url}) and set up OpenThread Border Router to communicate with it.",
|
|
6
7
|
"otbr_addon_already_running": "The OpenThread Border Router add-on is already running, it cannot be installed again.",
|
|
7
8
|
"otbr_still_using_stick": "This {model} is in use by the OpenThread Border Router add-on. If you use the Thread network, make sure you have alternative border routers. Uninstall the add-on and try again.",
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
"firmware_picker": {
|
|
3
3
|
"options": {
|
|
4
4
|
"abort": {
|
|
5
|
+
"fw_download_failed": "{firmware_name} firmware for your {model} failed to download. Make sure Home Assistant has internet access and try again.",
|
|
5
6
|
"not_hassio_thread": "The OpenThread Border Router add-on can only be installed with Home Assistant OS. If you would like to use the {model} as a Thread border router, please flash the firmware manually using the [web flasher]({docs_web_flasher_url}) and set up OpenThread Border Router to communicate with it.",
|
|
6
7
|
"otbr_addon_already_running": "The OpenThread Border Router add-on is already running, it cannot be installed again.",
|
|
7
8
|
"otbr_still_using_stick": "This {model} is in use by the OpenThread Border Router add-on. If you use the Thread network, make sure you have alternative border routers. Uninstall the add-on and try again.",
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"firmware_picker": {
|
|
3
|
+
"options": {
|
|
4
|
+
"progress": {
|
|
5
|
+
"install_firmware": "Fan go dt\u00ed go suite\u00e1lfar firmware {firmware_name} ar do {model}, t\u00f3gfaidh s\u00e9 seo c\u00fapla n\u00f3im\u00e9ad. N\u00e1 d\u00e9an aon athruithe ar do chrua-earra\u00ed n\u00e1 ar do bhogearra\u00ed go dt\u00ed go mbeidh s\u00e9 seo cr\u00edochnaithe."
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
{
|
|
2
|
+
"firmware_picker": {
|
|
3
|
+
"options": {
|
|
4
|
+
"progress": {
|
|
5
|
+
"install_firmware": "\u041f\u043e\u0447\u0435\u043a\u0430\u0458\u0442\u0435 \u0434\u043e\u0434\u0435\u043a\u0430 \u0444\u0438\u0440\u043c\u0432\u0435\u0440\u043e\u0442 {firmware_name} \u0441\u0435 \u0438\u043d\u0441\u0442\u0430\u043b\u0438\u0440\u0430 \u043d\u0430 \u0432\u0430\u0448\u0438\u043e\u0442 {model}, \u043e\u0432\u0430 \u045c\u0435 \u043f\u043e\u0442\u0440\u0430\u0435 \u043d\u0435\u043a\u043e\u043b\u043a\u0443 \u043c\u0438\u043d\u0443\u0442\u0438. \u041d\u0435 \u043f\u0440\u0430\u0432\u0435\u0442\u0435 \u043d\u0438\u043a\u0430\u043a\u0432\u0438 \u043f\u0440\u043e\u043c\u0435\u043d\u0438 \u043d\u0430 \u0432\u0430\u0448\u0438\u043e\u0442 \u0445\u0430\u0440\u0434\u0432\u0435\u0440 \u0438\u043b\u0438 \u0441\u043e\u0444\u0442\u0432\u0435\u0440 \u0434\u043e\u0434\u0435\u043a\u0430 \u043e\u0432\u0430 \u043d\u0435 \u0437\u0430\u0432\u0440\u0448\u0438."
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
}
|
|
@@ -93,7 +93,7 @@ class SkyConnectFirmwareMixin(ConfigEntryBaseFlow, FirmwareInstallFlowProtocol):
|
|
|
93
93
|
firmware_name="Zigbee",
|
|
94
94
|
expected_installed_firmware_type=ApplicationType.EZSP,
|
|
95
95
|
step_id="install_zigbee_firmware",
|
|
96
|
-
next_step_id="
|
|
96
|
+
next_step_id="pre_confirm_zigbee",
|
|
97
97
|
)
|
|
98
98
|
|
|
99
99
|
async def async_step_install_thread_firmware(
|
|
@@ -92,7 +92,8 @@
|
|
|
92
92
|
"otbr_addon_already_running": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::otbr_addon_already_running%]",
|
|
93
93
|
"zha_still_using_stick": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::zha_still_using_stick%]",
|
|
94
94
|
"otbr_still_using_stick": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::otbr_still_using_stick%]",
|
|
95
|
-
"unsupported_firmware": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::unsupported_firmware%]"
|
|
95
|
+
"unsupported_firmware": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::unsupported_firmware%]",
|
|
96
|
+
"fw_download_failed": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::fw_download_failed%]"
|
|
96
97
|
},
|
|
97
98
|
"progress": {
|
|
98
99
|
"install_addon": "[%key:component::homeassistant_hardware::silabs_multiprotocol_hardware::options::progress::install_addon%]",
|
|
@@ -145,7 +146,8 @@
|
|
|
145
146
|
"otbr_addon_already_running": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::otbr_addon_already_running%]",
|
|
146
147
|
"zha_still_using_stick": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::zha_still_using_stick%]",
|
|
147
148
|
"otbr_still_using_stick": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::otbr_still_using_stick%]",
|
|
148
|
-
"unsupported_firmware": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::unsupported_firmware%]"
|
|
149
|
+
"unsupported_firmware": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::unsupported_firmware%]",
|
|
150
|
+
"fw_download_failed": "[%key:component::homeassistant_hardware::firmware_picker::options::abort::fw_download_failed%]"
|
|
149
151
|
},
|
|
150
152
|
"progress": {
|
|
151
153
|
"install_addon": "[%key:component::homeassistant_hardware::silabs_multiprotocol_hardware::options::progress::install_addon%]",
|