fix: fix some type error

This commit is contained in:
topsworld 2024-12-23 22:01:06 +08:00
parent 13d76b66de
commit ab5fac9f45

View File

@ -101,37 +101,39 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
# pylint: disable=unused-argument, inconsistent-quotes
VERSION = 1
MINOR_VERSION = 1
DEFAULT_AREA_NAME_RULE = 'room'
_main_loop: asyncio.AbstractEventLoop
_mips_service: Optional[MipsService]
_miot_storage: Optional[MIoTStorage]
_miot_network: Optional[MIoTNetwork]
_miot_i18n: Optional[MIoTI18n]
_miot_network: MIoTNetwork
_mips_service: MipsService
_miot_storage: MIoTStorage
_miot_i18n: MIoTI18n
_integration_language: Optional[str]
_storage_path: Optional[str]
_virtual_did: Optional[str]
_uid: Optional[str]
_uuid: Optional[str]
_ctrl_mode: Optional[str]
_area_name_rule: Optional[str]
_integration_language: str
_storage_path: str
_virtual_did: str
_uid: str
_uuid: str
_ctrl_mode: str
_area_name_rule: str
_action_debug: bool
_hide_non_standard_entities: bool
_display_devices_changed_notify: bool
_auth_info: Optional[dict]
_nick_name: Optional[str]
_auth_info: dict
_nick_name: str
_home_selected: dict
_home_info_buffer: Optional[dict[str, str | dict[str, dict]]]
_home_list: Optional[dict]
_home_info_buffer: dict
_home_list_show: dict
_device_list_sorted: dict
_device_list_filter: dict
_cloud_server: Optional[str]
_oauth_redirect_url: Optional[str]
_cloud_server: str
_oauth_redirect_url_full: str
_miot_oauth: Optional[MIoTOauthClient]
_miot_http: Optional[MIoTHttpClient]
_user_cert_state: bool
_oauth_auth_url: Optional[str]
_oauth_auth_url: str
_task_oauth: Optional[asyncio.Task[None]]
_config_error_reason: Optional[str]
@ -139,70 +141,65 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
def __init__(self) -> None:
self._main_loop = asyncio.get_running_loop()
self._mips_service = None
self._miot_storage = None
self._miot_network = None
self._miot_i18n = None
self._integration_language = None
self._storage_path = None
self._virtual_did = None
self._uid = None
self._uuid = None # MQTT client id
self._ctrl_mode = None
self._area_name_rule = None
self._integration_language = DEFAULT_INTEGRATION_LANGUAGE
self._storage_path = ''
self._virtual_did = ''
self._uid = ''
self._uuid = '' # MQTT client id
self._ctrl_mode = DEFAULT_CTRL_MODE
self._area_name_rule = self.DEFAULT_AREA_NAME_RULE
self._action_debug = False
self._hide_non_standard_entities = False
self._display_devices_changed_notify = True
self._auth_info = None
self._nick_name = None
self._auth_info = {}
self._nick_name = DEFAULT_NICK_NAME
self._home_selected = {}
self._home_info_buffer = None
self._home_list = None
self._device_list_sorted = None
self._home_info_buffer = {}
self._home_list_show = {}
self._device_list_sorted = {}
self._cloud_server = None
self._oauth_redirect_url = None
self._cloud_server = DEFAULT_CLOUD_SERVER
self._oauth_redirect_url_full = ''
self._miot_oauth = None
self._miot_http = None
self._user_cert_state = False
self._oauth_auth_url = None
self._user_cert_state = False
self._oauth_auth_url = ''
self._task_oauth = None
self._config_error_reason = None
self._fut_oauth_code = None
async def async_step_user(self, user_input=None):
async def async_step_user(
self, user_input: Optional[dict] = None
):
self.hass.data.setdefault(DOMAIN, {})
loop: asyncio.AbstractEventLoop = asyncio.get_running_loop()
if self._virtual_did is None:
if not self._virtual_did:
self._virtual_did = str(secrets.randbits(64))
self.hass.data[DOMAIN].setdefault(self._virtual_did, {})
if self._storage_path is None:
if not self._storage_path:
self._storage_path = self.hass.config.path('.storage', DOMAIN)
# MIoT network
self._miot_network = self.hass.data[DOMAIN].get('miot_network', None)
if self._miot_network is None:
self._miot_network = MIoTNetwork(loop=loop)
if not self._miot_network:
self._miot_network = MIoTNetwork(loop=self._main_loop)
self.hass.data[DOMAIN]['miot_network'] = self._miot_network
await self._miot_network.init_async(
refresh_interval=NETWORK_REFRESH_INTERVAL)
_LOGGER.info('async_step_user, create miot network')
# Mips server
self._mips_service = self.hass.data[DOMAIN].get('mips_service', None)
if self._mips_service is None:
if not self._mips_service:
aiozc: HaAsyncZeroconf = await zeroconf.async_get_async_instance(
self.hass)
self._mips_service = MipsService(aiozc=aiozc, loop=loop)
self._mips_service = MipsService(aiozc=aiozc, loop=self._main_loop)
self.hass.data[DOMAIN]['mips_service'] = self._mips_service
await self._mips_service.init_async()
_LOGGER.info('async_step_user, create mips service')
# MIoT storage
self._miot_storage = self.hass.data[DOMAIN].get('miot_storage', None)
if self._miot_storage is None:
if not self._miot_storage:
self._miot_storage = MIoTStorage(
root_path=self._storage_path, loop=loop)
root_path=self._storage_path, loop=self._main_loop)
self.hass.data[DOMAIN]['miot_storage'] = self._miot_storage
_LOGGER.info(
'async_step_user, create miot storage, %s', self._storage_path)
@ -214,7 +211,9 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
return await self.async_step_eula(user_input)
async def async_step_eula(self, user_input=None):
async def async_step_eula(
self, user_input: Optional[dict] = None
):
if user_input:
if user_input.get('eula', None) is True:
return await self.async_step_auth_config()
@ -225,16 +224,18 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
return self.async_show_form(
step_id='eula',
data_schema=vol.Schema({
vol.Required('eula', default=False): bool,
vol.Required('eula', default=False): bool, # type: ignore
}),
last_step=False,
errors={'base': reason},
)
async def async_step_auth_config(self, user_input=None):
async def async_step_auth_config(
self, user_input: Optional[dict] = None
):
if user_input:
self._cloud_server = user_input.get(
'cloud_server', DEFAULT_CLOUD_SERVER)
'cloud_server', self._cloud_server)
self._integration_language = user_input.get(
'integration_language', DEFAULT_INTEGRATION_LANGUAGE)
self._miot_i18n = MIoTI18n(
@ -242,7 +243,7 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
await self._miot_i18n.init_async()
webhook_path = webhook_async_generate_path(
webhook_id=self._virtual_did)
self._oauth_redirect_url = (
self._oauth_redirect_url_full = (
f'{user_input.get("oauth_redirect_url")}{webhook_path}')
return await self.async_step_oauth(user_input)
# Generate default language from HomeAssistant config (not user config)
@ -257,33 +258,38 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
data_schema=vol.Schema({
vol.Required(
'cloud_server',
default=DEFAULT_CLOUD_SERVER): vol.In(CLOUD_SERVERS),
default=self._cloud_server # type: ignore
): vol.In(CLOUD_SERVERS),
vol.Required(
'integration_language',
default=default_language): vol.In(INTEGRATION_LANGUAGES),
default=default_language # type: ignore
): vol.In(INTEGRATION_LANGUAGES),
vol.Required(
'oauth_redirect_url',
default=OAUTH_REDIRECT_URL): vol.In([OAUTH_REDIRECT_URL]),
default=OAUTH_REDIRECT_URL # type: ignore
): vol.In([OAUTH_REDIRECT_URL]),
}),
last_step=False,
)
async def async_step_oauth(self, user_input=None):
async def async_step_oauth(
self, user_input: Optional[dict] = None
):
# 1: Init miot_oauth, generate auth url
try:
if self._miot_oauth is None:
if not self._miot_oauth:
_LOGGER.info(
'async_step_oauth, redirect_url: %s',
self._oauth_redirect_url)
self._oauth_redirect_url_full)
miot_oauth = MIoTOauthClient(
client_id=OAUTH2_CLIENT_ID,
redirect_url=self._oauth_redirect_url,
redirect_url=self._oauth_redirect_url_full,
cloud_server=self._cloud_server
)
state = str(secrets.randbits(64))
self.hass.data[DOMAIN][self._virtual_did]['oauth_state'] = state
self._oauth_auth_url = miot_oauth.gen_auth_url(
redirect_url=self._oauth_redirect_url, state=state)
redirect_url=self._oauth_redirect_url_full, state=state)
_LOGGER.info(
'async_step_oauth, oauth_url: %s', self._oauth_auth_url)
webhook_async_unregister(
@ -298,7 +304,7 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
)
self._fut_oauth_code = self.hass.data[DOMAIN][
self._virtual_did].get('fut_oauth_code', None)
if self._fut_oauth_code is None:
if not self._fut_oauth_code:
self._fut_oauth_code = self._main_loop.create_future()
self.hass.data[DOMAIN][self._virtual_did][
'fut_oauth_code'] = self._fut_oauth_code
@ -337,11 +343,16 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
async def __check_oauth_async(self) -> None:
# TASK 1: Get oauth code
if not self._fut_oauth_code:
raise MIoTConfigError('oauth_code_fut_error')
oauth_code: Optional[str] = await self._fut_oauth_code
if not oauth_code:
raise MIoTConfigError('oauth_code_error')
# TASK 2: Get access_token and user_info from miot_oauth
if not self._auth_info:
try:
if not self._miot_oauth:
raise MIoTConfigError('oauth_client_error')
auth_info = await self._miot_oauth.get_access_token_async(
code=oauth_code)
if not self._miot_http:
@ -363,7 +374,7 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
try:
self._nick_name = (
await self._miot_http.get_user_info_async() or {}
).get('miliaoNick', DEFAULT_NICK_NAME)
).get('miliaoNick', self._nick_name)
except (MIoTOauthError, json.JSONDecodeError):
self._nick_name = DEFAULT_NICK_NAME
_LOGGER.error('get nick name failed')
@ -374,6 +385,8 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
# TASK 3: Get home info
try:
if not self._miot_http:
raise MIoTConfigError('http_client_error')
self._home_info_buffer = (
await self._miot_http.get_devices_async())
_LOGGER.info('get_homeinfos response: %s', self._home_info_buffer)
@ -433,7 +446,7 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
f'{home_info["home_name"]} '
f'[ {len(dev_list)} {tip_devices} {tip_central} ]')
self._home_list = dict(sorted(home_list.items()))
self._home_list_show = dict(sorted(home_list.items()))
# TASK 7: Get user's MiHome certificate
if self._cloud_server in SUPPORT_CENTRAL_GATEWAY_CTRL:
@ -454,6 +467,8 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
user_key=user_key, did=self._virtual_did)
crt_str = await self._miot_http.get_central_cert_async(
csr_str)
if not crt_str:
raise MIoTError('get_central_cert_async failed')
if not await miot_cert.update_user_cert_async(
cert=crt_str):
raise MIoTError('update_user_cert_async failed')
@ -492,10 +507,12 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
errors={'base': error_reason},
)
async def async_step_homes_select(self, user_input=None):
async def async_step_homes_select(
self, user_input: Optional[dict] = None
):
_LOGGER.debug('async_step_homes_select')
try:
if user_input is None:
if not user_input:
return await self.__display_homes_select_form('')
home_selected: list = user_input.get('home_infos', [])
@ -506,7 +523,8 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
'homes']['home_list'].items():
if home_id in home_selected:
self._home_selected[home_id] = home_info
self._area_name_rule = user_input.get('area_name_rule')
self._area_name_rule = user_input.get(
'area_name_rule', self._area_name_rule)
# Storage device list
devices_list: dict[str, dict] = {
did: dev_info
@ -544,10 +562,16 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
return self.async_show_form(
step_id='homes_select',
data_schema=vol.Schema({
vol.Required('home_infos'): cv.multi_select(self._home_list),
vol.Required('area_name_rule', default='room'): vol.In(
self._miot_i18n.translate(key='config.room_name_rule')),
vol.Required('advanced_options', default=False): bool,
vol.Required('home_infos'): cv.multi_select(
self._home_list_show),
vol.Required(
'area_name_rule',
default=self._area_name_rule # type: ignore
): vol.In(self._miot_i18n.translate(
key='config.room_name_rule')),
vol.Required(
'advanced_options', default=False # type: ignore
): bool,
}),
errors={'base': reason},
description_placeholders={
@ -556,7 +580,9 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
last_step=False,
)
async def async_step_advanced_options(self, user_input: dict = None):
async def async_step_advanced_options(
self, user_input: Optional[dict] = None
):
if user_input:
self._ctrl_mode = user_input.get('ctrl_mode', self._ctrl_mode)
self._action_debug = user_input.get(
@ -570,16 +596,22 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
return self.async_show_form(
step_id='advanced_options',
data_schema=vol.Schema({
vol.Required('devices_filter', default=False): bool,
vol.Required('ctrl_mode', default=DEFAULT_CTRL_MODE): vol.In(
self._miot_i18n.translate(key='config.control_mode')),
vol.Required('action_debug', default=self._action_debug): bool,
vol.Required(
'devices_filter', default=False): bool, # type: ignore
vol.Required(
'ctrl_mode', default=self._ctrl_mode # type: ignore
): vol.In(self._miot_i18n.translate(key='config.control_mode')),
vol.Required(
'action_debug', default=self._action_debug # type: ignore
): bool,
vol.Required(
'hide_non_standard_entities',
default=self._hide_non_standard_entities): bool,
default=self._hide_non_standard_entities # type: ignore
): bool,
vol.Required(
'display_devices_changed_notify',
default=self._display_devices_changed_notify): bool,
default=self._display_devices_changed_notify # type: ignore
): bool,
}),
last_step=False,
)
@ -645,16 +677,17 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
return await self.__display_devices_filter_form(reason='')
async def __display_devices_filter_form(self, reason: str):
tip_devices: str = self._miot_i18n.translate(
key='config.other.devices')
key='config.other.devices') # type: ignore
tip_without_room: str = self._miot_i18n.translate(
key='config.other.without_room')
key='config.other.without_room') # type: ignore
trans_statistics_logic: dict = self._miot_i18n.translate(
key='config.statistics_logic')
key='config.statistics_logic') # type: ignore
trans_filter_mode: dict = self._miot_i18n.translate(
key='config.filter_mode')
key='config.filter_mode') # type: ignore
trans_connect_type: dict = self._miot_i18n.translate(
key='config.connect_type')
key='config.connect_type') # type: ignore
room_device_count: dict = {}
model_device_count: dict = {}
@ -692,22 +725,27 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
return self.async_show_form(
step_id='devices_filter',
data_schema=vol.Schema({
vol.Required('room_filter_mode', default='exclude'):
vol.In(trans_filter_mode),
vol.Required(
'room_filter_mode', default='exclude' # type: ignore
): vol.In(trans_filter_mode),
vol.Optional('room_list'): cv.multi_select(room_list),
vol.Required('type_filter_mode', default='exclude'):
vol.In(trans_filter_mode),
vol.Required(
'type_filter_mode', default='exclude' # type: ignore
): vol.In(trans_filter_mode),
vol.Optional('type_list'): cv.multi_select(type_list),
vol.Required('model_filter_mode', default='exclude'):
vol.In(trans_filter_mode),
vol.Required(
'model_filter_mode', default='exclude' # type: ignore
): vol.In(trans_filter_mode),
vol.Optional('model_list'): cv.multi_select(dict(sorted(
model_list.items(), key=lambda item: item[0]))),
vol.Required('devices_filter_mode', default='exclude'):
vol.In(trans_filter_mode),
vol.Required(
'devices_filter_mode', default='exclude' # type: ignore
): vol.In(trans_filter_mode),
vol.Optional('device_list'): cv.multi_select(dict(sorted(
device_list.items(), key=lambda device: device[1]))),
vol.Required('statistics_logic', default='or'):
vol.In(trans_statistics_logic),
vol.Required(
'statistics_logic', default='or' # type: ignore
): vol.In(trans_statistics_logic),
}),
errors={'base': reason},
last_step=False
@ -759,7 +797,7 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
'uid': self._uid,
'nick_name': self._nick_name,
'cloud_server': self._cloud_server,
'oauth_redirect_url': self._oauth_redirect_url,
'oauth_redirect_url': self._oauth_redirect_url_full,
'ctrl_mode': self._ctrl_mode,
'home_selected': self._home_selected,
'area_name_rule': self._area_name_rule,
@ -784,7 +822,7 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
# pylint: disable=inconsistent-quotes
_config_entry: config_entries.ConfigEntry
_main_loop: asyncio.AbstractEventLoop
_miot_client: Optional[MIoTClient]
_miot_client: MIoTClient
_miot_network: Optional[MIoTNetwork]
_miot_storage: Optional[MIoTStorage]
@ -799,7 +837,7 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
_uid: Optional[str]
_storage_path: Optional[str]
_cloud_server: Optional[str]
_oauth_redirect_url: Optional[str]
_oauth_redirect_url_full: str
_integration_language: Optional[str]
_ctrl_mode: Optional[str]
_nick_name: Optional[str]
@ -811,7 +849,7 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
_home_selected_dict: Optional[dict]
_home_info_buffer: Optional[dict[str, str | dict[str, dict]]]
_home_list: Optional[dict]
_device_list: Optional[dict[str, dict]]
_device_list: dict[str, dict]
_devices_add: list[str]
_devices_remove: list[str]
@ -851,7 +889,7 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
self._uid = self._entry_data['uid']
self._storage_path = self._entry_data['storage_path']
self._cloud_server = self._entry_data['cloud_server']
self._oauth_redirect_url = self._entry_data['oauth_redirect_url']
self._oauth_redirect_url_full = ''
self._ctrl_mode = self._entry_data['ctrl_mode']
self._integration_language = self._entry_data['integration_language']
self._nick_name = self._entry_data['nick_name']
@ -959,7 +997,7 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
if user_input:
webhook_path = webhook_async_generate_path(
webhook_id=self._virtual_did)
self._oauth_redirect_url = (
self._oauth_redirect_url_full = (
f'{user_input.get("oauth_redirect_url")}{webhook_path}')
return await self.async_step_oauth(user_input)
return self.async_show_form(
@ -981,9 +1019,9 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
state = str(secrets.randbits(64))
self.hass.data[DOMAIN][self._virtual_did]['oauth_state'] = state
self._miot_oauth.set_redirect_url(
redirect_url=self._oauth_redirect_url)
redirect_url=self._oauth_redirect_url_full)
self._oauth_auth_url = self._miot_oauth.gen_auth_url(
redirect_url=self._oauth_redirect_url, state=state)
redirect_url=self._oauth_redirect_url_full, state=state)
_LOGGER.info(
'async_step_oauth, oauth_url: %s',
self._oauth_auth_url)
@ -1166,7 +1204,9 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
self._nick_name_new = user_input.get('nick_name')
return await self.async_step_homes_select()
async def async_step_homes_select(self, user_input=None):
async def async_step_homes_select(
self, user_input: Optional[dict] = None
):
if not self._update_devices:
return await self.async_step_update_trans_rules()
if not user_input:
@ -1236,27 +1276,19 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
if dev_info['home_id'] in self._home_selected_list}
if not self._device_list:
return await self.__display_homes_select_form('no_devices')
# Statistics devices changed
self._devices_add = []
self._devices_remove = []
local_devices = await self._miot_storage.load_async(
domain='miot_devices',
name=f'{self._uid}_{self._cloud_server}',
type_=dict) or {}
self._device_list_sorted = dict(sorted(
self._device_list.items(), key=lambda item:
item[1].get('home_id', '')+item[1].get('room_id', '')))
self._devices_add = [
did for did in self._device_list.keys() if did not in local_devices]
self._devices_remove = [
did for did in local_devices.keys() if did not in self._device_list]
_LOGGER.debug(
'devices update, add->%s, remove->%s',
self._devices_add, self._devices_remove)
return await self.async_step_update_trans_rules()
if user_input.get('devices_filter', False):
return await self.async_step_devices_filter()
return await self.update_devices_done_async()
async def __display_homes_select_form(self, reason: str):
return self.async_show_form(
step_id='homes_select',
data_schema=vol.Schema({
vol.Required('devices_filter', default=False): bool,
vol.Required('home_infos', default=self._home_selected_list):
cv.multi_select(self._home_list),
vol.Required('ctrl_mode', default=self._ctrl_mode): vol.In(
@ -1269,6 +1301,100 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
last_step=False
)
async def async_step_devices_filter(
self, user_input: Optional[dict] = None
):
if user_input:
return await self.update_devices_done_async()
return await self.__display_devices_filter_form(reason='')
async def __display_devices_filter_form(self, reason: str):
tip_devices: str = self._miot_i18n.translate(
key='config.other.devices')
tip_without_room: str = self._miot_i18n.translate(
key='config.other.without_room')
trans_statistics_logic: dict = self._miot_i18n.translate(
key='config.statistics_logic')
trans_filter_mode: dict = self._miot_i18n.translate(
key='config.filter_mode')
trans_connect_type: dict = self._miot_i18n.translate(
key='config.connect_type')
room_device_count: dict = {}
model_device_count: dict = {}
connect_type_count: dict = {}
device_list: dict = {}
for did, info in self._device_list_sorted.items():
device_list[did] = (
f'[ {info["home_name"]} {info["room_name"]} ] ' +
f'{info["name"]}, {did}')
room_device_count.setdefault(info['room_id'], 0)
room_device_count[info['room_id']] += 1
model_device_count.setdefault(info['model'], 0)
model_device_count[info['model']] += 1
connect_type_count.setdefault(str(info['connect_type']), 0)
connect_type_count[str(info['connect_type'])] += 1
model_list: dict = {}
for model, count in model_device_count.items():
model_list[model] = f'{model} [ {count} {tip_devices} ]'
type_list: dict = {
k: f'{trans_connect_type.get(k, f"Connect Type ({k})")} '
f'[ {v} {tip_devices} ]'
for k, v in connect_type_count.items()}
room_list: dict = {}
for home_id, home_info in self._home_selected_dict.items():
for room_id, room_name in home_info['room_info'].items():
if room_id not in room_device_count:
continue
room_list[room_id] = (
f'{home_info["home_name"]} {room_name}'
f' [ {room_device_count[room_id]}{tip_devices} ]')
if home_id in room_device_count:
room_list[home_id] = (
f'{home_info["home_name"]} {tip_without_room}'
f' [ {room_device_count[home_id]}{tip_devices} ]')
return self.async_show_form(
step_id='devices_filter',
data_schema=vol.Schema({
vol.Required('room_filter_mode', default='exclude'):
vol.In(trans_filter_mode),
vol.Optional('room_list'): cv.multi_select(room_list),
vol.Required('type_filter_mode', default='exclude'):
vol.In(trans_filter_mode),
vol.Optional('type_list'): cv.multi_select(type_list),
vol.Required('model_filter_mode', default='exclude'):
vol.In(trans_filter_mode),
vol.Optional('model_list'): cv.multi_select(dict(sorted(
model_list.items(), key=lambda item: item[0]))),
vol.Required('devices_filter_mode', default='exclude'):
vol.In(trans_filter_mode),
vol.Optional('device_list'): cv.multi_select(dict(sorted(
device_list.items(), key=lambda device: device[1]))),
vol.Required('statistics_logic', default='or'):
vol.In(trans_statistics_logic),
}),
errors={'base': reason},
last_step=False
)
async def update_devices_done_async(self):
# Statistics devices changed
self._devices_add = []
self._devices_remove = []
local_devices: dict = await self._miot_storage.load_async(
domain='miot_devices',
name=f'{self._uid}_{self._cloud_server}',
type_=dict) or {} # type: ignore
self._devices_add = [
did for did in self._device_list.keys() if did not in local_devices]
self._devices_remove = [
did for did in local_devices.keys() if did not in self._device_list]
_LOGGER.debug(
'devices update, add->%s, remove->%s',
self._devices_add, self._devices_remove)
return await self.async_step_update_trans_rules()
async def async_step_update_trans_rules(self, user_input=None):
if not self._update_trans_rules:
return await self.async_step_update_lan_ctrl_config()
@ -1397,7 +1523,6 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
last_step=True
)
self._entry_data['oauth_redirect_url'] = self._oauth_redirect_url
if self._lang_new != self._integration_language:
self._entry_data['integration_language'] = self._lang_new
self._need_reload = True