ha(H2): ниты повторного ревью — pump без параллельных читателей, pending-рефкаунт, точная ошибка свойств

- session.py: новый лог-памп не поднимается, пока предыдущий не завершился
  (stopping/is_alive), параллельное чтение кольца исключено
- __init__: счётчик pending закрывает окно гонки setup/unload последней
  записи; warning при не-словарном fglair: в YAML
- trial: properties_missing — отдельная ошибка формы/abort (en/ru/strings)
- ConfigEntryNotReady: «порт 0» больше не показывается
- тесты: контраст одинакового явного порта, неблокирующий unload (тикер loop)
- план H5: публикация pyfglair именно на PyPI (manylinux x86_64/aarch64)
This commit is contained in:
2026-09-29 12:29:35 +03:00
parent da01c607a6
commit 29f62b639c
9 changed files with 109 additions and 26 deletions
+22 -9
View File
@@ -24,6 +24,7 @@ _LOG_LEVELS = {
}
DATA_CLIENTS = f"{DOMAIN}_clients"
DATA_PENDING = f"{DOMAIN}_pending"
def _log_handler(level: int, message: str) -> None:
@@ -31,22 +32,34 @@ def _log_handler(level: int, message: str) -> None:
async def async_setup(hass: HomeAssistant, config: dict) -> bool:
if isinstance(config.get(DOMAIN), dict):
hass.async_create_task(
hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data=config[DOMAIN],
)
if DOMAIN not in config:
return True
if not isinstance(config[DOMAIN], dict):
_LOGGER.warning(
"fglair: ожидался словарь параметров устройства, получено %s",
type(config[DOMAIN]).__name__,
)
return True
hass.async_create_task(
hass.config_entries.flow.async_init(
DOMAIN,
context={"source": config_entries.SOURCE_IMPORT},
data=config[DOMAIN],
)
)
return True
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
clients: dict[str, FglairClient] = hass.data.setdefault(DATA_CLIENTS, {})
hass.data[DATA_PENDING] = hass.data.get(DATA_PENDING, 0) + 1
client = FglairClient(hass, entry.data)
await client.async_start()
try:
await client.async_start()
finally:
hass.data[DATA_PENDING] -= 1
clients[entry.entry_id] = client
entry.runtime_data = client
if len(clients) == 1:
@@ -64,6 +77,6 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
clients: dict[str, FglairClient] = hass.data.get(DATA_CLIENTS, {})
clients.pop(entry.entry_id, None)
if not clients:
if not clients and not hass.data.get(DATA_PENDING, 0):
await hass.async_add_executor_job(pyfglair.set_log_handler, None)
return True