ha(H4): repair key_mismatch, диагностика для ESPHome, reconfigure, переводы

- repairs: issue key_mismatch (ERROR, fixable) при состоянии key_error,
  ConfirmRepairFlow, снятие issue при online/unload/remove
- config flow: async_step_reconfigure (меню, prefill ручной формы,
  unique_id_mismatch, update_reload_and_abort) — путь «перепровижинировать»
- diagnostics: config/esp_home (dsn/lanip_key/key_id/host для secrets.yaml)
  + esp_home_masked и redacted entry_data, runtime-снимок значений
  (raw/display) из кэша ядра
- translations: issues.key_mismatch (title/description/fix_flow) en/ru,
  abort unique_id_mismatch/reconfigure_successful; тест согласованности
  strings↔en↔ru
- FglairClient.events_dropped; mock_ac: параметр key_id в фикстуре
- тесты: diagnostics, repairs issue+fix-flow, reconfigure (успех/чужое
  устройство), translations (45 components)
This commit is contained in:
2026-09-29 14:06:39 +03:00
parent dee5819743
commit 57ee555704
15 changed files with 451 additions and 10 deletions
+9 -1
View File
@@ -7,10 +7,11 @@ from homeassistant import config_entries
from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform
from homeassistant.core import HomeAssistant
from homeassistant.helpers import issue_registry as ir
import pyfglair
from .const import DOMAIN
from .const import CONF_DSN, DOMAIN
from .coordinator import FglairCoordinator, FglairRuntime
from .fglair_client import FglairClient
from .overrides import ConversionSet
@@ -98,9 +99,16 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
return False
await runtime.coordinator.async_shutdown()
await runtime.client.async_stop()
ir.async_delete_issue(hass, DOMAIN, runtime.coordinator.key_issue_id)
clients: dict[str, FglairClient] = hass.data.get(DATA_CLIENTS, {})
clients.pop(entry.entry_id, None)
if not clients and not hass.data.get(DATA_PENDING, 0):
await hass.async_add_executor_job(pyfglair.set_log_handler, None)
return unloaded
async def async_remove_entry(hass: HomeAssistant, entry: ConfigEntry) -> None:
ir.async_delete_issue(
hass, DOMAIN, f"key_mismatch_{entry.data.get(CONF_DSN)}"
)