* knx entity CRUD - initial commit - switch * platform dependent schema * coerce empty GA-lists to None * read entity configuration from WS * use entity_id instead of unique_id for lookup * Add device support * Rename KNXEntityStore to KNXConfigStore * fix test after rename * Send schema options for creating / editing entities * Return entity_id after entity creation * remove device_class config in favour of more-info-dialog settings * refactor group address schema for custom selector * Rename GA keys and remove invalid keys from schema * fix rebase * Fix deleting devices and their entities * Validate entity schema in extra step - return validation infos * Use exception to signal validation error; return validated data * Forward validation result when editing entities * Get proper validation error message for optional GAs * Add entity validation only WS command * use ulid instead of uuid * Fix error handling for edit unknown entity * Remove unused optional group address sets from validated schema * Add optional dpt field for ga_schema * Move knx config things to sub-key * Add light platform * async_forward_entry_setups only once * Test crate and remove devices * Test removing entities of a removed device * Test entity creation and storage * Test deleting entities * Test unsuccessful entity creation * Test updating entity data * Test get entity config * Test validate entity * Update entity data by entity_id instead of unique_id * Remove unnecessary uid unique check * remove schema_options * test fixture for entity creation * clean up group address schema class can be used to add custom serializer later * Revert: Add light platfrom * remove unused optional_ga_schema * Test GASelector * lint tests * Review * group entities before adding * fix / ignore mypy * always has_entity_name * Entity name: check for empty string when no device * use constants instead of strings in schema * Fix mypy errors for voluptuous schemas --------- Co-authored-by: Marc Mueller <30130371+cdce8p@users.noreply.github.com>
48 lines
1.5 KiB
Python
48 lines
1.5 KiB
Python
"""KNX Keyring handler."""
|
|
|
|
import logging
|
|
from pathlib import Path
|
|
import shutil
|
|
from typing import Final
|
|
|
|
from xknx.exceptions.exception import InvalidSecureConfiguration
|
|
from xknx.secure.keyring import Keyring, sync_load_keyring
|
|
|
|
from homeassistant.components.file_upload import process_uploaded_file
|
|
from homeassistant.core import HomeAssistant
|
|
from homeassistant.helpers.storage import STORAGE_DIR
|
|
|
|
from ..const import DOMAIN
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
DEFAULT_KNX_KEYRING_FILENAME: Final = "keyring.knxkeys"
|
|
|
|
|
|
async def save_uploaded_knxkeys_file(
|
|
hass: HomeAssistant, uploaded_file_id: str, password: str
|
|
) -> Keyring:
|
|
"""Validate the uploaded file and move it to the storage directory.
|
|
|
|
Return a Keyring object.
|
|
Raises InvalidSecureConfiguration if the file or password is invalid.
|
|
"""
|
|
|
|
def _process_upload() -> Keyring:
|
|
with process_uploaded_file(hass, uploaded_file_id) as file_path:
|
|
try:
|
|
keyring = sync_load_keyring(
|
|
path=file_path,
|
|
password=password,
|
|
)
|
|
except InvalidSecureConfiguration as err:
|
|
_LOGGER.debug(err)
|
|
raise
|
|
dest_path = Path(hass.config.path(STORAGE_DIR, DOMAIN))
|
|
dest_path.mkdir(exist_ok=True)
|
|
dest_file = dest_path / DEFAULT_KNX_KEYRING_FILENAME
|
|
shutil.move(file_path, dest_file)
|
|
return keyring
|
|
|
|
return await hass.async_add_executor_job(_process_upload)
|