homeassistant 2025.11.0b2__py3-none-any.whl → 2025.11.0b5__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.
Files changed (209) hide show
  1. homeassistant/components/alexa_devices/manifest.json +1 -1
  2. homeassistant/components/alexa_devices/translations/bg.json +13 -0
  3. homeassistant/components/ambient_network/sensor.py +5 -5
  4. homeassistant/components/blink/translations/bg.json +8 -1
  5. homeassistant/components/brother/translations/bg.json +0 -6
  6. homeassistant/components/brother/translations/ca.json +1 -5
  7. homeassistant/components/brother/translations/cs.json +2 -2
  8. homeassistant/components/brother/translations/da.json +1 -5
  9. homeassistant/components/brother/translations/de.json +4 -4
  10. homeassistant/components/brother/translations/el.json +1 -5
  11. homeassistant/components/brother/translations/en-GB.json +4 -4
  12. homeassistant/components/brother/translations/en.json +4 -4
  13. homeassistant/components/brother/translations/es-419.json +0 -5
  14. homeassistant/components/brother/translations/es.json +2 -2
  15. homeassistant/components/brother/translations/et.json +2 -2
  16. homeassistant/components/brother/translations/fi.json +1 -5
  17. homeassistant/components/brother/translations/fr.json +1 -5
  18. homeassistant/components/brother/translations/ga.json +2 -10
  19. homeassistant/components/brother/translations/hu.json +1 -5
  20. homeassistant/components/brother/translations/id.json +1 -5
  21. homeassistant/components/brother/translations/it.json +1 -5
  22. homeassistant/components/brother/translations/ja.json +1 -5
  23. homeassistant/components/brother/translations/ko.json +1 -5
  24. homeassistant/components/brother/translations/lb.json +1 -2
  25. homeassistant/components/brother/translations/lt.json +2 -2
  26. homeassistant/components/brother/translations/nb.json +1 -5
  27. homeassistant/components/brother/translations/nl.json +1 -5
  28. homeassistant/components/brother/translations/pl.json +3 -7
  29. homeassistant/components/brother/translations/pt-BR.json +1 -5
  30. homeassistant/components/brother/translations/pt.json +2 -10
  31. homeassistant/components/brother/translations/ro.json +1 -2
  32. homeassistant/components/brother/translations/ru.json +1 -5
  33. homeassistant/components/brother/translations/sk.json +2 -2
  34. homeassistant/components/brother/translations/sl.json +2 -10
  35. homeassistant/components/brother/translations/sv.json +2 -10
  36. homeassistant/components/brother/translations/tr.json +1 -5
  37. homeassistant/components/brother/translations/uk.json +1 -5
  38. homeassistant/components/brother/translations/vi.json +1 -5
  39. homeassistant/components/brother/translations/zh-Hans.json +2 -2
  40. homeassistant/components/brother/translations/zh-Hant.json +4 -4
  41. homeassistant/components/bryant_evolution/translations/lt.json +3 -0
  42. homeassistant/components/control4/translations/es.json +2 -1
  43. homeassistant/components/cover/translations/es.json +7 -7
  44. homeassistant/components/daikin/translations/es.json +1 -0
  45. homeassistant/components/ecovacs/translations/es.json +27 -0
  46. homeassistant/components/ecovacs/translations/sr-Latn.json +18 -0
  47. homeassistant/components/esphome/__init__.py +5 -3
  48. homeassistant/components/esphome/translations/he.json +2 -2
  49. homeassistant/components/fing/translations/bg.json +20 -0
  50. homeassistant/components/fing/translations/es.json +31 -0
  51. homeassistant/components/firefly_iii/translations/bg.json +3 -0
  52. homeassistant/components/foscam/manifest.json +1 -1
  53. homeassistant/components/frontend/__init__.py +1 -1
  54. homeassistant/components/frontend/manifest.json +1 -1
  55. homeassistant/components/google_sheets/translations/bg.json +10 -0
  56. homeassistant/components/google_sheets/translations/es.json +9 -0
  57. homeassistant/components/google_sheets/translations/sr-Latn.json +14 -0
  58. homeassistant/components/habitica/translations/es.json +26 -0
  59. homeassistant/components/hassio/issues.py +0 -2
  60. homeassistant/components/hassio/translations/es.json +13 -0
  61. homeassistant/components/holiday/manifest.json +1 -1
  62. homeassistant/components/homeassistant_connect_zbt2/config_flow.py +1 -1
  63. homeassistant/components/homewizard/translations/es.json +4 -2
  64. homeassistant/components/inels/translations/bg.json +1 -0
  65. homeassistant/components/inels/translations/es.json +30 -0
  66. homeassistant/components/jewish_calendar/translations/es.json +6 -0
  67. homeassistant/components/knx/translations/bg.json +93 -0
  68. homeassistant/components/knx/translations/es.json +39 -8
  69. homeassistant/components/knx/translations/sr-Latn.json +44 -1
  70. homeassistant/components/lametric/translations/es.json +1 -0
  71. homeassistant/components/lg_thinq/sensor.py +1 -0
  72. homeassistant/components/litterrobot/manifest.json +1 -1
  73. homeassistant/components/london_underground/translations/he.json +1 -0
  74. homeassistant/components/matrix/translations/bg.json +2 -1
  75. homeassistant/components/matter/translations/bg.json +7 -0
  76. homeassistant/components/matter/translations/es.json +26 -3
  77. homeassistant/components/mcp/translations/es.json +4 -0
  78. homeassistant/components/mqtt/translations/es.json +4 -4
  79. homeassistant/components/mqtt/translations/he.json +2 -2
  80. homeassistant/components/nederlandse_spoorwegen/translations/bg.json +2 -1
  81. homeassistant/components/nextdns/translations/bg.json +2 -1
  82. homeassistant/components/nina/translations/bg.json +0 -6
  83. homeassistant/components/nina/translations/es.json +40 -1
  84. homeassistant/components/nina/translations/sr-Latn.json +28 -0
  85. homeassistant/components/nintendo_parental_controls/translations/bg.json +19 -0
  86. homeassistant/components/nuki/translations/es.json +4 -0
  87. homeassistant/components/octoprint/translations/es.json +16 -0
  88. homeassistant/components/oralb/translations/es.json +1 -0
  89. homeassistant/components/overkiz/translations/lt.json +2 -1
  90. homeassistant/components/plugwise/climate.py +86 -26
  91. homeassistant/components/plugwise/manifest.json +1 -1
  92. homeassistant/components/plugwise/strings.json +3 -0
  93. homeassistant/components/plugwise/translations/de.json +3 -0
  94. homeassistant/components/plugwise/translations/en.json +3 -0
  95. homeassistant/components/plugwise/translations/sk.json +3 -0
  96. homeassistant/components/portainer/translations/bg.json +8 -1
  97. homeassistant/components/portainer/translations/sr-Latn.json +3 -1
  98. homeassistant/components/probe_plus/translations/es.json +5 -0
  99. homeassistant/components/ps4/translations/es.json +9 -1
  100. homeassistant/components/reolink/manifest.json +1 -1
  101. homeassistant/components/reolink/translations/cs.json +1 -0
  102. homeassistant/components/reolink/translations/en-GB.json +1 -0
  103. homeassistant/components/reolink/translations/es.json +1 -0
  104. homeassistant/components/reolink/translations/et.json +1 -0
  105. homeassistant/components/reolink/translations/lt.json +1 -0
  106. homeassistant/components/reolink/translations/pl.json +8 -7
  107. homeassistant/components/reolink/translations/sk.json +1 -0
  108. homeassistant/components/ruuvitag_ble/manifest.json +1 -1
  109. homeassistant/components/shelly/translations/bg.json +2 -1
  110. homeassistant/components/shelly/translations/es.json +10 -3
  111. homeassistant/components/slide_local/translations/es.json +1 -1
  112. homeassistant/components/smarttub/manifest.json +1 -1
  113. homeassistant/components/somfy_mylink/translations/es.json +3 -3
  114. homeassistant/components/soundtouch/__init__.py +10 -1
  115. homeassistant/components/sql/translations/es.json +27 -0
  116. homeassistant/components/sql/translations/sr-Latn.json +9 -0
  117. homeassistant/components/squeezebox/translations/es.json +63 -0
  118. homeassistant/components/sunricher_dali_center/translations/bg.json +19 -0
  119. homeassistant/components/switch_as_x/translations/es.json +4 -4
  120. homeassistant/components/system_bridge/translations/es.json +1 -0
  121. homeassistant/components/telegram_bot/translations/bg.json +11 -0
  122. homeassistant/components/telegram_bot/translations/es.json +42 -7
  123. homeassistant/components/template/translations/es.json +11 -3
  124. homeassistant/components/tesla_fleet/manifest.json +1 -1
  125. homeassistant/components/teslemetry/manifest.json +1 -1
  126. homeassistant/components/tessie/manifest.json +1 -1
  127. homeassistant/components/tessie/translations/es.json +3 -0
  128. homeassistant/components/transmission/translations/bg.json +10 -0
  129. homeassistant/components/usb/utils.py +22 -23
  130. homeassistant/components/vesync/humidifier.py +3 -1
  131. homeassistant/components/vesync/strings.json +11 -0
  132. homeassistant/components/vesync/translations/bg.json +11 -0
  133. homeassistant/components/vesync/translations/cs.json +11 -0
  134. homeassistant/components/vesync/translations/de.json +11 -0
  135. homeassistant/components/vesync/translations/en.json +11 -0
  136. homeassistant/components/vesync/translations/es.json +11 -0
  137. homeassistant/components/vesync/translations/et.json +11 -0
  138. homeassistant/components/vesync/translations/he.json +11 -0
  139. homeassistant/components/vesync/translations/lt.json +11 -0
  140. homeassistant/components/vesync/translations/sk.json +11 -0
  141. homeassistant/components/vesync/translations/zh-Hans.json +11 -0
  142. homeassistant/components/vesync/translations/zh-Hant.json +11 -0
  143. homeassistant/components/volvo/translations/bg.json +5 -0
  144. homeassistant/components/volvo/translations/cs.json +5 -0
  145. homeassistant/components/volvo/translations/en-GB.json +5 -0
  146. homeassistant/components/volvo/translations/es.json +11 -0
  147. homeassistant/components/volvo/translations/lt.json +5 -0
  148. homeassistant/components/volvo/translations/sk.json +5 -0
  149. homeassistant/components/whirlpool/translations/bg.json +22 -0
  150. homeassistant/components/whirlpool/translations/es.json +81 -0
  151. homeassistant/components/workday/manifest.json +1 -1
  152. homeassistant/components/xbox/translations/bg.json +36 -0
  153. homeassistant/components/xbox/translations/es.json +21 -0
  154. homeassistant/components/xbox/translations/sr-Latn.json +1 -0
  155. homeassistant/components/yardian/translations/bg.json +7 -0
  156. homeassistant/components/yardian/translations/es.json +16 -0
  157. homeassistant/components/zha/__init__.py +16 -1
  158. homeassistant/components/zha/config_flow.py +156 -46
  159. homeassistant/components/zha/manifest.json +1 -1
  160. homeassistant/components/zha/strings.json +68 -15
  161. homeassistant/components/zha/translations/bg.json +0 -4
  162. homeassistant/components/zha/translations/ca.json +0 -3
  163. homeassistant/components/zha/translations/cs.json +30 -16
  164. homeassistant/components/zha/translations/da.json +0 -3
  165. homeassistant/components/zha/translations/de.json +68 -15
  166. homeassistant/components/zha/translations/el.json +0 -3
  167. homeassistant/components/zha/translations/en-GB.json +0 -18
  168. homeassistant/components/zha/translations/en.json +68 -15
  169. homeassistant/components/zha/translations/es.json +81 -19
  170. homeassistant/components/zha/translations/et.json +30 -16
  171. homeassistant/components/zha/translations/fi.json +0 -3
  172. homeassistant/components/zha/translations/fr.json +0 -18
  173. homeassistant/components/zha/translations/ga.json +0 -3
  174. homeassistant/components/zha/translations/gsw.json +0 -3
  175. homeassistant/components/zha/translations/hu.json +0 -3
  176. homeassistant/components/zha/translations/id.json +0 -3
  177. homeassistant/components/zha/translations/it.json +0 -3
  178. homeassistant/components/zha/translations/ja.json +0 -3
  179. homeassistant/components/zha/translations/ko.json +0 -9
  180. homeassistant/components/zha/translations/lt.json +0 -18
  181. homeassistant/components/zha/translations/nb.json +0 -3
  182. homeassistant/components/zha/translations/nl.json +0 -3
  183. homeassistant/components/zha/translations/pl.json +0 -3
  184. homeassistant/components/zha/translations/pt-BR.json +0 -3
  185. homeassistant/components/zha/translations/pt.json +0 -18
  186. homeassistant/components/zha/translations/ro.json +0 -3
  187. homeassistant/components/zha/translations/ru.json +0 -18
  188. homeassistant/components/zha/translations/sk.json +68 -15
  189. homeassistant/components/zha/translations/sl.json +0 -9
  190. homeassistant/components/zha/translations/sr-Latn.json +0 -14
  191. homeassistant/components/zha/translations/sv.json +0 -4
  192. homeassistant/components/zha/translations/tr.json +0 -3
  193. homeassistant/components/zha/translations/uk.json +0 -3
  194. homeassistant/components/zha/translations/zh-Hans.json +30 -16
  195. homeassistant/components/zha/translations/zh-Hant.json +30 -16
  196. homeassistant/components/zwave_js/translations/es.json +3 -0
  197. homeassistant/const.py +1 -1
  198. homeassistant/generated/integrations.json +0 -5
  199. homeassistant/package_constraints.txt +1 -1
  200. homeassistant/util/language.py +17 -7
  201. {homeassistant-2025.11.0b2.dist-info → homeassistant-2025.11.0b5.dist-info}/METADATA +1 -1
  202. {homeassistant-2025.11.0b2.dist-info → homeassistant-2025.11.0b5.dist-info}/RECORD +207 -204
  203. homeassistant/components/enmax/__init__.py +0 -1
  204. homeassistant/components/enmax/manifest.json +0 -6
  205. {homeassistant-2025.11.0b2.dist-info → homeassistant-2025.11.0b5.dist-info}/WHEEL +0 -0
  206. {homeassistant-2025.11.0b2.dist-info → homeassistant-2025.11.0b5.dist-info}/entry_points.txt +0 -0
  207. {homeassistant-2025.11.0b2.dist-info → homeassistant-2025.11.0b5.dist-info}/licenses/LICENSE.md +0 -0
  208. {homeassistant-2025.11.0b2.dist-info → homeassistant-2025.11.0b5.dist-info}/licenses/homeassistant/backports/LICENSE.Python +0 -0
  209. {homeassistant-2025.11.0b2.dist-info → homeassistant-2025.11.0b5.dist-info}/top_level.txt +0 -0
@@ -20,6 +20,22 @@
20
20
  }
21
21
  }
22
22
  },
23
+ "entity": {
24
+ "binary_sensor": {
25
+ "freeze_prevent": {
26
+ "name": "Prevenci\u00f3n de congelaci\u00f3n"
27
+ },
28
+ "standby": {
29
+ "name": "En espera"
30
+ },
31
+ "watering_running": {
32
+ "name": "Riego en ejecuci\u00f3n"
33
+ },
34
+ "zone_enabled": {
35
+ "name": "Zona {zone} habilitada"
36
+ }
37
+ }
38
+ },
23
39
  "services": {
24
40
  "start_irrigation": {
25
41
  "description": "Inicia el riego.",
@@ -17,6 +17,7 @@ from homeassistant.components.homeassistant_hardware.helpers import (
17
17
  async_notify_firmware_info,
18
18
  async_register_firmware_info_provider,
19
19
  )
20
+ from homeassistant.components.usb import usb_device_from_path
20
21
  from homeassistant.config_entries import ConfigEntry
21
22
  from homeassistant.const import (
22
23
  CONF_TYPE,
@@ -134,6 +135,21 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
134
135
 
135
136
  Will automatically load components to support devices found on the network.
136
137
  """
138
+
139
+ # Try to perform an in-place migration if we detect that the device path can be made
140
+ # unique
141
+ device_path = config_entry.data[CONF_DEVICE][CONF_DEVICE_PATH]
142
+ usb_device = await hass.async_add_executor_job(usb_device_from_path, device_path)
143
+
144
+ if usb_device is not None and device_path != usb_device.device:
145
+ _LOGGER.info(
146
+ "Migrating ZHA device path from %s to %s", device_path, usb_device.device
147
+ )
148
+ new_data = {**config_entry.data}
149
+ new_data[CONF_DEVICE][CONF_DEVICE_PATH] = usb_device.device
150
+ hass.config_entries.async_update_entry(config_entry, data=new_data)
151
+ device_path = usb_device.device
152
+
137
153
  ha_zha_data: HAZHAData = get_zha_data(hass)
138
154
  ha_zha_data.config_entry = config_entry
139
155
  zha_lib_data: ZHAData = create_zha_config(hass, ha_zha_data)
@@ -163,7 +179,6 @@ async def async_setup_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> b
163
179
  _LOGGER.debug("Trigger cache: %s", zha_lib_data.device_trigger_cache)
164
180
 
165
181
  # Check if firmware update is in progress for this device
166
- device_path = config_entry.data[CONF_DEVICE][CONF_DEVICE_PATH]
167
182
  _raise_if_port_in_use(hass, device_path)
168
183
 
169
184
  try:
@@ -3,14 +3,14 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  from abc import abstractmethod
6
+ import asyncio
6
7
  import collections
7
8
  from contextlib import suppress
8
9
  from enum import StrEnum
9
10
  import json
11
+ import os
10
12
  from typing import Any
11
13
 
12
- import serial.tools.list_ports
13
- from serial.tools.list_ports_common import ListPortInfo
14
14
  import voluptuous as vol
15
15
  from zha.application.const import RadioType
16
16
  import zigpy.backups
@@ -25,6 +25,7 @@ from homeassistant.components.homeassistant_hardware.firmware_config_flow import
25
25
  ZigbeeFlowStrategy,
26
26
  )
27
27
  from homeassistant.components.homeassistant_yellow import hardware as yellow_hardware
28
+ from homeassistant.components.usb import USBDevice, scan_serial_ports
28
29
  from homeassistant.config_entries import (
29
30
  SOURCE_IGNORE,
30
31
  SOURCE_ZEROCONF,
@@ -38,7 +39,7 @@ from homeassistant.config_entries import (
38
39
  )
39
40
  from homeassistant.const import CONF_NAME
40
41
  from homeassistant.core import HomeAssistant, callback
41
- from homeassistant.data_entry_flow import AbortFlow
42
+ from homeassistant.data_entry_flow import AbortFlow, progress_step
42
43
  from homeassistant.exceptions import HomeAssistantError
43
44
  from homeassistant.helpers.hassio import is_hassio
44
45
  from homeassistant.helpers.selector import FileSelector, FileSelectorConfig
@@ -124,10 +125,10 @@ def _format_backup_choice(
124
125
  return f"{dt_util.as_local(backup.backup_time).strftime('%c')} ({identifier})"
125
126
 
126
127
 
127
- async def list_serial_ports(hass: HomeAssistant) -> list[ListPortInfo]:
128
+ async def list_serial_ports(hass: HomeAssistant) -> list[USBDevice]:
128
129
  """List all serial ports, including the Yellow radio and the multi-PAN addon."""
129
- ports: list[ListPortInfo] = []
130
- ports.extend(await hass.async_add_executor_job(serial.tools.list_ports.comports))
130
+ ports: list[USBDevice] = []
131
+ ports.extend(await hass.async_add_executor_job(scan_serial_ports))
131
132
 
132
133
  # Add useful info to the Yellow's serial port selection screen
133
134
  try:
@@ -137,9 +138,14 @@ async def list_serial_ports(hass: HomeAssistant) -> list[ListPortInfo]:
137
138
  else:
138
139
  # PySerial does not properly handle the Yellow's serial port with the CM5
139
140
  # so we manually include it
140
- port = ListPortInfo(device="/dev/ttyAMA1", skip_link_detection=True)
141
- port.description = "Yellow Zigbee module"
142
- port.manufacturer = "Nabu Casa"
141
+ port = USBDevice(
142
+ device="/dev/ttyAMA1",
143
+ vid="ffff", # This is technically not a USB device
144
+ pid="ffff",
145
+ serial_number=None,
146
+ manufacturer="Nabu Casa",
147
+ description="Yellow Zigbee module",
148
+ )
143
149
 
144
150
  ports = [p for p in ports if not p.device.startswith("/dev/ttyAMA")]
145
151
  ports.insert(0, port)
@@ -156,13 +162,15 @@ async def list_serial_ports(hass: HomeAssistant) -> list[ListPortInfo]:
156
162
  addon_info = None
157
163
 
158
164
  if addon_info is not None and addon_info.state != AddonState.NOT_INSTALLED:
159
- addon_port = ListPortInfo(
165
+ addon_port = USBDevice(
160
166
  device=silabs_multiprotocol_addon.get_zigbee_socket(),
161
- skip_link_detection=True,
167
+ vid="ffff", # This is technically not a USB device
168
+ pid="ffff",
169
+ serial_number=None,
170
+ manufacturer="Nabu Casa",
171
+ description="Silicon Labs Multiprotocol add-on",
162
172
  )
163
173
 
164
- addon_port.description = "Multiprotocol add-on"
165
- addon_port.manufacturer = "Nabu Casa"
166
174
  ports.append(addon_port)
167
175
 
168
176
  return ports
@@ -172,6 +180,7 @@ class BaseZhaFlow(ConfigEntryBaseFlow):
172
180
  """Mixin for common ZHA flow steps and forms."""
173
181
 
174
182
  _flow_strategy: ZigbeeFlowStrategy | None = None
183
+ _overwrite_ieee_during_restore: bool = False
175
184
  _hass: HomeAssistant
176
185
  _title: str
177
186
 
@@ -181,6 +190,7 @@ class BaseZhaFlow(ConfigEntryBaseFlow):
181
190
 
182
191
  self._hass = None # type: ignore[assignment]
183
192
  self._radio_mgr = ZhaRadioManager()
193
+ self._restore_backup_task: asyncio.Task[None] | None = None
184
194
 
185
195
  @property
186
196
  def hass(self) -> HomeAssistant:
@@ -218,8 +228,15 @@ class BaseZhaFlow(ConfigEntryBaseFlow):
218
228
  ) -> ConfigFlowResult:
219
229
  """Choose a serial port."""
220
230
  ports = await list_serial_ports(self.hass)
231
+
232
+ # The full `/dev/serial/by-id/` path is too verbose to show
233
+ resolved_paths = {
234
+ p.device: await self.hass.async_add_executor_job(os.path.realpath, p.device)
235
+ for p in ports
236
+ }
237
+
221
238
  list_of_ports = [
222
- f"{p}{', s/n: ' + p.serial_number if p.serial_number else ''}"
239
+ f"{resolved_paths[p.device]} - {p.description}{', s/n: ' + p.serial_number if p.serial_number else ''}"
223
240
  + (f" - {p.manufacturer}" if p.manufacturer else "")
224
241
  for p in ports
225
242
  ]
@@ -446,6 +463,7 @@ class BaseZhaFlow(ConfigEntryBaseFlow):
446
463
  self._radio_mgr.chosen_backup = self._radio_mgr.backups[0]
447
464
  return await self.async_step_maybe_reset_old_radio()
448
465
 
466
+ @progress_step()
449
467
  async def async_step_maybe_reset_old_radio(
450
468
  self, user_input: dict[str, Any] | None = None
451
469
  ) -> ConfigFlowResult:
@@ -473,9 +491,69 @@ class BaseZhaFlow(ConfigEntryBaseFlow):
473
491
  temp_radio_mgr.device_settings = config_entry.data[CONF_DEVICE]
474
492
  temp_radio_mgr.radio_type = RadioType[config_entry.data[CONF_RADIO_TYPE]]
475
493
 
476
- await temp_radio_mgr.async_reset_adapter()
494
+ try:
495
+ await temp_radio_mgr.async_reset_adapter()
496
+ except HomeAssistantError:
497
+ # Old adapter not found or cannot connect, show prompt to plug back in
498
+ return await self.async_step_plug_in_old_radio()
499
+
500
+ return await self.async_step_restore_backup()
477
501
 
478
- return await self.async_step_maybe_confirm_ezsp_restore()
502
+ async def async_step_plug_in_old_radio(
503
+ self, user_input: dict[str, Any] | None = None
504
+ ) -> ConfigFlowResult:
505
+ """Prompt user to plug in the old radio if connection fails."""
506
+ config_entries = self.hass.config_entries.async_entries(
507
+ DOMAIN, include_ignore=False
508
+ )
509
+
510
+ # Unless the user removes the config entry whilst we try to reset the old radio
511
+ # for a few seconds and then also unplugs it, we will basically never hit this
512
+ if not config_entries:
513
+ return await self.async_step_restore_backup()
514
+
515
+ config_entry = config_entries[0]
516
+ old_device_path = config_entry.data[CONF_DEVICE][CONF_DEVICE_PATH]
517
+
518
+ return self.async_show_menu(
519
+ step_id="plug_in_old_radio",
520
+ menu_options=["retry_old_radio", "skip_reset_old_radio"],
521
+ description_placeholders={"device_path": old_device_path},
522
+ )
523
+
524
+ async def async_step_retry_old_radio(
525
+ self, user_input: dict[str, Any] | None = None
526
+ ) -> ConfigFlowResult:
527
+ """Retry connecting to the old radio."""
528
+ return await self.async_step_maybe_reset_old_radio()
529
+
530
+ async def async_step_skip_reset_old_radio(
531
+ self, user_input: dict[str, Any] | None = None
532
+ ) -> ConfigFlowResult:
533
+ """Skip resetting the old radio and continue with migration."""
534
+ return await self.async_step_restore_backup()
535
+
536
+ async def async_step_pre_plug_in_new_radio(
537
+ self, user_input: dict[str, Any] | None = None
538
+ ) -> ConfigFlowResult:
539
+ """Strip user_input before showing "plug in new radio" form."""
540
+ # This step is necessary to prevent `user_input` from being passed through
541
+ return await self.async_step_plug_in_new_radio()
542
+
543
+ async def async_step_plug_in_new_radio(
544
+ self, user_input: dict[str, Any] | None = None
545
+ ) -> ConfigFlowResult:
546
+ """Prompt user to plug in the new radio if connection fails."""
547
+ if user_input is not None:
548
+ # User confirmed, retry now
549
+ return await self.async_step_restore_backup()
550
+
551
+ assert self._radio_mgr.device_path is not None
552
+
553
+ return self.async_show_form(
554
+ step_id="plug_in_new_radio",
555
+ description_placeholders={"device_path": self._radio_mgr.device_path},
556
+ )
479
557
 
480
558
  async def async_step_migration_strategy_advanced(
481
559
  self, user_input: dict[str, Any] | None = None
@@ -539,6 +617,7 @@ class BaseZhaFlow(ConfigEntryBaseFlow):
539
617
  # This step exists only for translations, it does nothing new
540
618
  return await self.async_step_form_new_network(user_input)
541
619
 
620
+ @progress_step()
542
621
  async def async_step_form_new_network(
543
622
  self, user_input: dict[str, Any] | None = None
544
623
  ) -> ConfigFlowResult:
@@ -624,47 +703,78 @@ class BaseZhaFlow(ConfigEntryBaseFlow):
624
703
  ),
625
704
  )
626
705
 
627
- async def async_step_maybe_confirm_ezsp_restore(
706
+ async def async_step_restore_backup(
628
707
  self, user_input: dict[str, Any] | None = None
629
708
  ) -> ConfigFlowResult:
630
- """Confirm restore for EZSP radios that require permanent IEEE writes."""
631
- if user_input is not None:
632
- if user_input[OVERWRITE_COORDINATOR_IEEE]:
633
- # On confirmation, overwrite destructively
634
- try:
635
- await self._radio_mgr.restore_backup(overwrite_ieee=True)
636
- except CannotWriteNetworkSettings as exc:
637
- return self.async_abort(
638
- reason="cannot_restore_backup",
639
- description_placeholders={"error": str(exc)},
640
- )
641
-
642
- return await self._async_create_radio_entry()
709
+ """Restore network backup to new radio."""
710
+ if self._restore_backup_task is None:
711
+ self._restore_backup_task = self.hass.async_create_task(
712
+ self._radio_mgr.restore_backup(
713
+ overwrite_ieee=self._overwrite_ieee_during_restore
714
+ ),
715
+ "Restore backup",
716
+ )
643
717
 
644
- # On rejection, explain why we can't restore
645
- return self.async_abort(reason="cannot_restore_backup_no_ieee_confirm")
718
+ if not self._restore_backup_task.done():
719
+ return self.async_show_progress(
720
+ step_id="restore_backup",
721
+ progress_action="restore_backup",
722
+ progress_task=self._restore_backup_task,
723
+ )
646
724
 
647
- # On first attempt, just try to restore nondestructively
648
725
  try:
649
- await self._radio_mgr.restore_backup()
726
+ await self._restore_backup_task
650
727
  except DestructiveWriteNetworkSettings:
651
- # Restore cannot happen automatically, we need to ask for permission
652
- pass
728
+ # If we cannot restore without overwriting the IEEE, ask for confirmation
729
+ return self.async_show_progress_done(
730
+ next_step_id="pre_confirm_ezsp_ieee_overwrite"
731
+ )
732
+ except HomeAssistantError:
733
+ # User unplugged the new adapter, allow retry
734
+ return self.async_show_progress_done(next_step_id="pre_plug_in_new_radio")
653
735
  except CannotWriteNetworkSettings as exc:
654
736
  return self.async_abort(
655
737
  reason="cannot_restore_backup",
656
738
  description_placeholders={"error": str(exc)},
657
739
  )
658
- else:
659
- return await self._async_create_radio_entry()
740
+ finally:
741
+ self._restore_backup_task = None
660
742
 
661
- # If it fails, show the form
662
- return self.async_show_form(
663
- step_id="maybe_confirm_ezsp_restore",
664
- data_schema=vol.Schema(
665
- {vol.Required(OVERWRITE_COORDINATOR_IEEE, default=True): bool}
666
- ),
667
- )
743
+ # Otherwise, proceed to entry creation
744
+ return self.async_show_progress_done(next_step_id="create_entry")
745
+
746
+ async def async_step_pre_confirm_ezsp_ieee_overwrite(
747
+ self, user_input: dict[str, Any] | None = None
748
+ ) -> ConfigFlowResult:
749
+ """Strip user_input before showing confirmation form."""
750
+ # This step is necessary to prevent `user_input` from being passed through
751
+ return await self.async_step_confirm_ezsp_ieee_overwrite()
752
+
753
+ async def async_step_confirm_ezsp_ieee_overwrite(
754
+ self, user_input: dict[str, Any] | None = None
755
+ ) -> ConfigFlowResult:
756
+ """Show confirmation form for EZSP IEEE address overwrite."""
757
+ if user_input is None:
758
+ return self.async_show_form(
759
+ step_id="confirm_ezsp_ieee_overwrite",
760
+ data_schema=vol.Schema(
761
+ {vol.Required(OVERWRITE_COORDINATOR_IEEE, default=True): bool}
762
+ ),
763
+ )
764
+
765
+ if not user_input[OVERWRITE_COORDINATOR_IEEE]:
766
+ return self.async_abort(reason="cannot_restore_backup_no_ieee_confirm")
767
+
768
+ self._overwrite_ieee_during_restore = True
769
+ return await self.async_step_restore_backup()
770
+
771
+ async def async_step_create_entry(
772
+ self, user_input: dict[str, Any] | None = None
773
+ ) -> ConfigFlowResult:
774
+ """Create the config entry after successful setup/migration."""
775
+
776
+ # This step only exists so that we can create entries from other steps
777
+ return await self._async_create_radio_entry()
668
778
 
669
779
 
670
780
  class ZhaConfigFlowHandler(BaseZhaFlow, ConfigFlow, domain=DOMAIN):
@@ -1018,7 +1128,7 @@ class ZhaOptionsFlowHandler(BaseZhaFlow, OptionsFlow):
1018
1128
 
1019
1129
  # If we are reconfiguring, the old radio will not be available
1020
1130
  if self._migration_intent is OptionsMigrationIntent.RECONFIGURE:
1021
- return await self.async_step_maybe_confirm_ezsp_restore()
1131
+ return await self.async_step_restore_backup()
1022
1132
 
1023
1133
  return await super().async_step_maybe_reset_old_radio(user_input)
1024
1134
 
@@ -21,7 +21,7 @@
21
21
  "zha",
22
22
  "universal_silabs_flasher"
23
23
  ],
24
- "requirements": ["zha==0.0.75"],
24
+ "requirements": ["zha==0.0.77"],
25
25
  "usb": [
26
26
  {
27
27
  "description": "*2652*",
@@ -16,6 +16,11 @@
16
16
  "invalid_backup_json": "Invalid backup JSON"
17
17
  },
18
18
  "flow_title": "{name}",
19
+ "progress": {
20
+ "form_new_network": "Forming a new Zigbee network.\n\nWe scan for a clear network channel as part of this process, this can take a minute.",
21
+ "maybe_reset_old_radio": "Resetting old adapter.\n\nYour old adapter has been backed up and is being factory reset.",
22
+ "restore_backup": "Restoring network settings to new adapter.\n\nThis will take a minute."
23
+ },
19
24
  "step": {
20
25
  "choose_automatic_backup": {
21
26
  "data": {
@@ -76,8 +81,15 @@
76
81
  "confirm": {
77
82
  "description": "Do you want to set up {name}?"
78
83
  },
79
- "confirm_hardware": {
80
- "description": "Do you want to set up {name}?"
84
+ "confirm_ezsp_ieee_overwrite": {
85
+ "data": {
86
+ "overwrite_coordinator_ieee": "Permanently replace the adapter IEEE address"
87
+ },
88
+ "description": "Your backup has a different IEEE address than your adapter. For your network to function properly, the IEEE address of your adapter should also be changed.\n\nThis is a permanent operation.",
89
+ "title": "Overwrite adapter IEEE address"
90
+ },
91
+ "form_new_network": {
92
+ "title": "Forming new network"
81
93
  },
82
94
  "manual_pick_radio_type": {
83
95
  "data": {
@@ -100,17 +112,28 @@
100
112
  "description": "ZHA was not able to automatically detect serial port settings for your adapter. This usually is an issue with the firmware or permissions.\n\nIf you are using firmware with nonstandard settings, enter the serial port settings",
101
113
  "title": "Serial port settings"
102
114
  },
103
- "maybe_confirm_ezsp_restore": {
104
- "data": {
105
- "overwrite_coordinator_ieee": "Permanently replace the adapter IEEE address"
106
- },
107
- "description": "Your backup has a different IEEE address than your adapter. For your network to function properly, the IEEE address of your adapter should also be changed.\n\nThis is a permanent operation.",
108
- "title": "Overwrite adapter IEEE address"
109
- },
110
115
  "maybe_reset_old_radio": {
111
- "description": "A backup was created earlier and your old adapter is being reset as part of the migration.",
112
116
  "title": "Resetting old adapter"
113
117
  },
118
+ "plug_in_new_radio": {
119
+ "description": "Your new adapter at `{device_path}` was not found.\nPlease plug it in and click Submit to continue.",
120
+ "title": "New adapter not found"
121
+ },
122
+ "plug_in_old_radio": {
123
+ "description": "Your old adapter at `{device_path}` was not found. You can retry after plugging it back in, or skip resetting the old adapter.\n\n**Warning:** If you skip resetting the old adapter, ensure it remains permanently disconnected. Plugging it back in later will cause network issues.",
124
+ "menu_option_descriptions": {
125
+ "retry_old_radio": "Retry connecting to the old adapter to reset it as part of the migration.",
126
+ "skip_reset_old_radio": "Skip resetting the old adapter and continue with the migration."
127
+ },
128
+ "menu_options": {
129
+ "retry_old_radio": "Retry",
130
+ "skip_reset_old_radio": "Skip reset"
131
+ },
132
+ "title": "Old adapter not found"
133
+ },
134
+ "restore_backup": {
135
+ "title": "Restoring network to new adapter"
136
+ },
114
137
  "upload_manual_backup": {
115
138
  "data": {
116
139
  "uploaded_backup_file": "Upload a file"
@@ -1869,6 +1892,11 @@
1869
1892
  "invalid_backup_json": "[%key:component::zha::config::error::invalid_backup_json%]"
1870
1893
  },
1871
1894
  "flow_title": "[%key:component::zha::config::flow_title%]",
1895
+ "progress": {
1896
+ "form_new_network": "[%key:component::zha::config::progress::form_new_network%]",
1897
+ "maybe_reset_old_radio": "[%key:component::zha::config::progress::maybe_reset_old_radio%]",
1898
+ "restore_backup": "[%key:component::zha::config::progress::restore_backup%]"
1899
+ },
1872
1900
  "step": {
1873
1901
  "choose_automatic_backup": {
1874
1902
  "data": {
@@ -1914,6 +1942,16 @@
1914
1942
  "description": "[%key:component::zha::config::step::choose_serial_port::description%]",
1915
1943
  "title": "[%key:component::zha::config::step::choose_serial_port::title%]"
1916
1944
  },
1945
+ "confirm_ezsp_ieee_overwrite": {
1946
+ "data": {
1947
+ "overwrite_coordinator_ieee": "[%key:component::zha::config::step::confirm_ezsp_ieee_overwrite::data::overwrite_coordinator_ieee%]"
1948
+ },
1949
+ "description": "[%key:component::zha::config::step::confirm_ezsp_ieee_overwrite::description%]",
1950
+ "title": "[%key:component::zha::config::step::confirm_ezsp_ieee_overwrite::title%]"
1951
+ },
1952
+ "form_new_network": {
1953
+ "title": "[%key:component::zha::config::step::form_new_network::title%]"
1954
+ },
1917
1955
  "init": {
1918
1956
  "description": "A backup will be performed and ZHA will be stopped. Do you wish to continue?",
1919
1957
  "title": "Reconfigure ZHA"
@@ -1938,12 +1976,24 @@
1938
1976
  "description": "[%key:component::zha::config::step::manual_port_config::description%]",
1939
1977
  "title": "[%key:component::zha::config::step::manual_port_config::title%]"
1940
1978
  },
1941
- "maybe_confirm_ezsp_restore": {
1942
- "data": {
1943
- "overwrite_coordinator_ieee": "[%key:component::zha::config::step::maybe_confirm_ezsp_restore::data::overwrite_coordinator_ieee%]"
1979
+ "maybe_reset_old_radio": {
1980
+ "title": "[%key:component::zha::config::step::maybe_reset_old_radio::title%]"
1981
+ },
1982
+ "plug_in_new_radio": {
1983
+ "description": "[%key:component::zha::config::step::plug_in_new_radio::description%]",
1984
+ "title": "[%key:component::zha::config::step::plug_in_new_radio::title%]"
1985
+ },
1986
+ "plug_in_old_radio": {
1987
+ "description": "[%key:component::zha::config::step::plug_in_old_radio::description%]",
1988
+ "menu_option_descriptions": {
1989
+ "retry_old_radio": "[%key:component::zha::config::step::plug_in_old_radio::menu_option_descriptions::retry_old_radio%]",
1990
+ "skip_reset_old_radio": "[%key:component::zha::config::step::plug_in_old_radio::menu_option_descriptions::skip_reset_old_radio%]"
1991
+ },
1992
+ "menu_options": {
1993
+ "retry_old_radio": "[%key:component::zha::config::step::plug_in_old_radio::menu_options::retry_old_radio%]",
1994
+ "skip_reset_old_radio": "[%key:component::zha::config::step::plug_in_old_radio::menu_options::skip_reset_old_radio%]"
1944
1995
  },
1945
- "description": "[%key:component::zha::config::step::maybe_confirm_ezsp_restore::description%]",
1946
- "title": "[%key:component::zha::config::step::maybe_confirm_ezsp_restore::title%]"
1996
+ "title": "[%key:component::zha::config::step::plug_in_old_radio::title%]"
1947
1997
  },
1948
1998
  "prompt_migrate_or_reconfigure": {
1949
1999
  "description": "Are you migrating to a new adapter or re-configuring the current adapter?",
@@ -1957,6 +2007,9 @@
1957
2007
  },
1958
2008
  "title": "Migrate or re-configure"
1959
2009
  },
2010
+ "restore_backup": {
2011
+ "title": "[%key:component::zha::config::step::restore_backup::title%]"
2012
+ },
1960
2013
  "upload_manual_backup": {
1961
2014
  "data": {
1962
2015
  "uploaded_backup_file": "[%key:component::zha::config::step::upload_manual_backup::data::uploaded_backup_file%]"
@@ -58,9 +58,6 @@
58
58
  "confirm": {
59
59
  "description": "\u0418\u0441\u043a\u0430\u0442\u0435 \u043b\u0438 \u0434\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u0435 {name}?"
60
60
  },
61
- "confirm_hardware": {
62
- "description": "\u0418\u0441\u043a\u0430\u0442\u0435 \u043b\u0438 \u0434\u0430 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u0435 {name}?"
63
- },
64
61
  "manual_port_config": {
65
62
  "data_description": {
66
63
  "baudrate": "\u0421\u043a\u043e\u0440\u043e\u0441\u0442 \u043d\u0430 \u043f\u0440\u0435\u0434\u0430\u0432\u0430\u043d\u0435, \u043a\u043e\u044f\u0442\u043e \u0434\u0430 \u0441\u0435 \u0438\u0437\u043f\u043e\u043b\u0437\u0432\u0430 \u043f\u0440\u0438 \u043a\u043e\u043c\u0443\u043d\u0438\u043a\u0430\u0446\u0438\u044f \u0441\u044a\u0441 \u0441\u0435\u0440\u0438\u0439\u043d\u0438\u044f \u043f\u043e\u0440\u0442, \u043e\u0431\u0438\u043a\u043d\u043e\u0432\u0435\u043d\u043e 115200 \u0438\u043b\u0438 460800",
@@ -69,7 +66,6 @@
69
66
  }
70
67
  },
71
68
  "maybe_reset_old_radio": {
72
- "description": "\u041f\u043e-\u0440\u0430\u043d\u043e \u0431\u0435\u0448\u0435 \u0441\u044a\u0437\u0434\u0430\u0434\u0435\u043d\u043e \u0440\u0435\u0437\u0435\u0440\u0432\u043d\u043e \u043a\u043e\u043f\u0438\u0435 \u0438 \u0441\u0442\u0430\u0440\u0438\u044f\u0442 \u0432\u0438 \u0430\u0434\u0430\u043f\u0442\u0435\u0440 \u0441\u0435 \u043d\u0443\u043b\u0438\u0440\u0430 \u043a\u0430\u0442\u043e \u0447\u0430\u0441\u0442 \u043e\u0442 \u043c\u0438\u0433\u0440\u0430\u0446\u0438\u044f\u0442\u0430.",
73
69
  "title": "\u041d\u0443\u043b\u0438\u0440\u0430\u043d\u0435 \u043d\u0430 \u0441\u0442\u0430\u0440\u0438\u044f \u0430\u0434\u0430\u043f\u0442\u0435\u0440"
74
70
  },
75
71
  "upload_manual_backup": {
@@ -27,9 +27,6 @@
27
27
  "confirm": {
28
28
  "description": "Vols configurar {name}?"
29
29
  },
30
- "confirm_hardware": {
31
- "description": "Vols configurar {name}?"
32
- },
33
30
  "manual_port_config": {
34
31
  "data": {
35
32
  "path": "Ruta del port s\u00e8rie al dispositiu"
@@ -76,9 +76,6 @@
76
76
  "confirm": {
77
77
  "description": "Chcete nastavit {name}?"
78
78
  },
79
- "confirm_hardware": {
80
- "description": "Chcete nastavit {name}?"
81
- },
82
79
  "manual_pick_radio_type": {
83
80
  "data": {
84
81
  "radio_type": "Typ adapt\u00e9ru"
@@ -100,17 +97,25 @@
100
97
  "description": "ZHA nedok\u00e1zala automaticky detekovat nastaven\u00ed s\u00e9riov\u00e9ho portu pro v\u00e1\u0161 adapt\u00e9r. Obvykle se jedn\u00e1 o probl\u00e9m s firmwarem nebo opr\u00e1vn\u011bn\u00edmi.\n \nPokud pou\u017e\u00edv\u00e1te firmware s nestandardn\u00edm nastaven\u00edm, zadejte nastaven\u00ed s\u00e9riov\u00e9ho portu.",
101
98
  "title": "Nastaven\u00ed s\u00e9riov\u00e9ho portu"
102
99
  },
103
- "maybe_confirm_ezsp_restore": {
104
- "data": {
105
- "overwrite_coordinator_ieee": "Trvale nahradit IEEE adresu adapt\u00e9ru"
106
- },
107
- "description": "Va\u0161e z\u00e1loha m\u00e1 jinou adresu IEEE ne\u017e v\u00e1\u0161 adapt\u00e9r. Aby s\u00ed\u0165 fungovala spr\u00e1vn\u011b, m\u011bla by b\u00fdt zm\u011bn\u011bna tak\u00e9 adresa IEEE va\u0161eho adapt\u00e9ru.\n\nJedn\u00e1 se o trvalou operaci.",
108
- "title": "P\u0159epsat adresu IEEE adapt\u00e9ru"
109
- },
110
100
  "maybe_reset_old_radio": {
111
- "description": "Z\u00e1loha byla vytvo\u0159ena d\u0159\u00edve a v\u00e1\u0161 star\u00fd adapt\u00e9r se v r\u00e1mci migrace resetuje.",
112
101
  "title": "Resetov\u00e1n\u00ed star\u00e9ho adapt\u00e9ru"
113
102
  },
103
+ "plug_in_new_radio": {
104
+ "description": "V\u00e1\u0161 nov\u00fd adapt\u00e9r na adrese \"{device_path}\" nebyl nalezen.\nZapojte jej a klepn\u011bte na tla\u010d\u00edtko Odeslat pro pokra\u010dov\u00e1n\u00ed.",
105
+ "title": "Nov\u00fd adapt\u00e9r nebyl nalezen"
106
+ },
107
+ "plug_in_old_radio": {
108
+ "description": "V\u00e1\u0161 star\u00fd adapt\u00e9r na adrese \"{device_path}\" nebyl nalezen. M\u016f\u017eete to zkusit znovu po jeho op\u011btovn\u00e9m zapojen\u00ed nebo p\u0159esko\u010dit resetov\u00e1n\u00ed star\u00e9ho adapt\u00e9ru.\n \n**Varov\u00e1n\u00ed:** Pokud resetov\u00e1n\u00ed star\u00e9ho adapt\u00e9ru p\u0159esko\u010d\u00edte, ujist\u011bte se, \u017ee z\u016fstane trvale odpojen\u00fd. Jeho pozd\u011bj\u0161\u00ed op\u011btovn\u00e9 p\u0159ipojen\u00ed zp\u016fsob\u00ed probl\u00e9my se s\u00edt\u00ed.",
109
+ "menu_option_descriptions": {
110
+ "retry_old_radio": "Zkuste se znovu p\u0159ipojit ke star\u00e9mu adapt\u00e9ru, abyste jej v r\u00e1mci migrace resetovali.",
111
+ "skip_reset_old_radio": "P\u0159esko\u010d\u00ed resetov\u00e1n\u00ed star\u00e9ho adapt\u00e9ru a pokra\u010duje v migraci."
112
+ },
113
+ "menu_options": {
114
+ "retry_old_radio": "Opakovat",
115
+ "skip_reset_old_radio": "P\u0159esko\u010dit resetov\u00e1n\u00ed"
116
+ },
117
+ "title": "Star\u00fd adapt\u00e9r nebyl nalezen"
118
+ },
114
119
  "upload_manual_backup": {
115
120
  "data": {
116
121
  "uploaded_backup_file": "Nahr\u00e1t soubor"
@@ -1938,12 +1943,21 @@
1938
1943
  "description": "ZHA nedok\u00e1zala automaticky detekovat nastaven\u00ed s\u00e9riov\u00e9ho portu pro v\u00e1\u0161 adapt\u00e9r. Obvykle se jedn\u00e1 o probl\u00e9m s firmwarem nebo opr\u00e1vn\u011bn\u00edmi.\n \nPokud pou\u017e\u00edv\u00e1te firmware s nestandardn\u00edm nastaven\u00edm, zadejte nastaven\u00ed s\u00e9riov\u00e9ho portu.",
1939
1944
  "title": "Nastaven\u00ed s\u00e9riov\u00e9ho portu"
1940
1945
  },
1941
- "maybe_confirm_ezsp_restore": {
1942
- "data": {
1943
- "overwrite_coordinator_ieee": "Trvale nahradit IEEE adresu adapt\u00e9ru"
1946
+ "plug_in_new_radio": {
1947
+ "description": "V\u00e1\u0161 nov\u00fd adapt\u00e9r na adrese \"{device_path}\" nebyl nalezen.\nZapojte jej a klepn\u011bte na tla\u010d\u00edtko Odeslat pro pokra\u010dov\u00e1n\u00ed.",
1948
+ "title": "Nov\u00fd adapt\u00e9r nebyl nalezen"
1949
+ },
1950
+ "plug_in_old_radio": {
1951
+ "description": "V\u00e1\u0161 star\u00fd adapt\u00e9r na adrese \"{device_path}\" nebyl nalezen. M\u016f\u017eete to zkusit znovu po jeho op\u011btovn\u00e9m zapojen\u00ed nebo p\u0159esko\u010dit resetov\u00e1n\u00ed star\u00e9ho adapt\u00e9ru.\n \n**Varov\u00e1n\u00ed:** Pokud resetov\u00e1n\u00ed star\u00e9ho adapt\u00e9ru p\u0159esko\u010d\u00edte, ujist\u011bte se, \u017ee z\u016fstane trvale odpojen\u00fd. Jeho pozd\u011bj\u0161\u00ed op\u011btovn\u00e9 p\u0159ipojen\u00ed zp\u016fsob\u00ed probl\u00e9my se s\u00edt\u00ed.",
1952
+ "menu_option_descriptions": {
1953
+ "retry_old_radio": "Zkuste se znovu p\u0159ipojit ke star\u00e9mu adapt\u00e9ru, abyste jej v r\u00e1mci migrace resetovali.",
1954
+ "skip_reset_old_radio": "P\u0159esko\u010d\u00ed resetov\u00e1n\u00ed star\u00e9ho adapt\u00e9ru a pokra\u010duje v migraci."
1955
+ },
1956
+ "menu_options": {
1957
+ "retry_old_radio": "Opakovat",
1958
+ "skip_reset_old_radio": "P\u0159esko\u010dit resetov\u00e1n\u00ed"
1944
1959
  },
1945
- "description": "Va\u0161e z\u00e1loha m\u00e1 jinou adresu IEEE ne\u017e v\u00e1\u0161 adapt\u00e9r. Aby s\u00ed\u0165 fungovala spr\u00e1vn\u011b, m\u011bla by b\u00fdt zm\u011bn\u011bna tak\u00e9 adresa IEEE va\u0161eho adapt\u00e9ru.\n\nJedn\u00e1 se o trvalou operaci.",
1946
- "title": "P\u0159epsat adresu IEEE adapt\u00e9ru"
1960
+ "title": "Star\u00fd adapt\u00e9r nebyl nalezen"
1947
1961
  },
1948
1962
  "prompt_migrate_or_reconfigure": {
1949
1963
  "description": "P\u0159ech\u00e1z\u00edte na nov\u00fd adapt\u00e9r nebo m\u011bn\u00edte nastaven\u00ed st\u00e1vaj\u00edc\u00edho adapt\u00e9ru?",
@@ -26,9 +26,6 @@
26
26
  "confirm": {
27
27
  "description": "Vil du konfigurere {name}?"
28
28
  },
29
- "confirm_hardware": {
30
- "description": "Vil du konfigurere {name}?"
31
- },
32
29
  "manual_pick_radio_type": {
33
30
  "data": {
34
31
  "radio_type": "Adaptertype"