mirror of
https://github.com/XiaoMi/ha_xiaomi_home.git
synced 2026-01-16 14:40:43 +08:00
feat: support option flow devices filter
This commit is contained in:
parent
24e85b358a
commit
cd0b13e49e
@ -654,7 +654,7 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
include_items['did'] = device_list_in
|
include_items['did'] = device_list_in
|
||||||
else:
|
else:
|
||||||
exclude_items['did'] = device_list_in
|
exclude_items['did'] = device_list_in
|
||||||
device_filter_list = self.__devices_filter(
|
device_filter_list = _handle_devices_filter(
|
||||||
devices=self._device_list_sorted,
|
devices=self._device_list_sorted,
|
||||||
logic_or=(user_input.get('statistics_logic', 'or') == 'or'),
|
logic_or=(user_input.get('statistics_logic', 'or') == 'or'),
|
||||||
item_in=include_items, item_ex=exclude_items)
|
item_in=include_items, item_ex=exclude_items)
|
||||||
@ -751,39 +751,6 @@ class XiaomiMihomeConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
|
|||||||
last_step=False
|
last_step=False
|
||||||
)
|
)
|
||||||
|
|
||||||
def __devices_filter(
|
|
||||||
self, devices: dict, logic_or: bool, item_in: dict, item_ex: dict
|
|
||||||
) -> dict:
|
|
||||||
include_set: Set = set([])
|
|
||||||
if not item_in:
|
|
||||||
include_set = set(devices.keys())
|
|
||||||
else:
|
|
||||||
filter_item: list[set] = []
|
|
||||||
for key, value in item_in.items():
|
|
||||||
filter_item.append(set([
|
|
||||||
did for did, info in devices.items()
|
|
||||||
if str(info[key]) in value]))
|
|
||||||
include_set = (
|
|
||||||
set.union(*filter_item)
|
|
||||||
if logic_or else set.intersection(*filter_item))
|
|
||||||
if not include_set:
|
|
||||||
return {}
|
|
||||||
if item_ex:
|
|
||||||
filter_item: list[set] = []
|
|
||||||
for key, value in item_ex.items():
|
|
||||||
filter_item.append(set([
|
|
||||||
did for did, info in devices.items()
|
|
||||||
if str(info[key]) in value]))
|
|
||||||
exclude_set: Set = (
|
|
||||||
set.union(*filter_item)
|
|
||||||
if logic_or else set.intersection(*filter_item))
|
|
||||||
if exclude_set:
|
|
||||||
include_set = include_set-exclude_set
|
|
||||||
if not include_set:
|
|
||||||
return {}
|
|
||||||
return {
|
|
||||||
did: info for did, info in devices.items() if did in include_set}
|
|
||||||
|
|
||||||
async def config_flow_done(self):
|
async def config_flow_done(self):
|
||||||
return self.async_create_entry(
|
return self.async_create_entry(
|
||||||
title=(
|
title=(
|
||||||
@ -1292,13 +1259,13 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
|
|||||||
return self.async_show_form(
|
return self.async_show_form(
|
||||||
step_id='homes_select',
|
step_id='homes_select',
|
||||||
data_schema=vol.Schema({
|
data_schema=vol.Schema({
|
||||||
vol.Required(
|
|
||||||
'devices_filter', default=False # type: ignore
|
|
||||||
): bool,
|
|
||||||
vol.Required(
|
vol.Required(
|
||||||
'home_infos',
|
'home_infos',
|
||||||
default=self._home_selected_list # type: ignore
|
default=self._home_selected_list # type: ignore
|
||||||
): cv.multi_select(self._home_list_show),
|
): cv.multi_select(self._home_list_show),
|
||||||
|
vol.Required(
|
||||||
|
'devices_filter', default=False # type: ignore
|
||||||
|
): bool,
|
||||||
vol.Required(
|
vol.Required(
|
||||||
'ctrl_mode', default=self._ctrl_mode # type: ignore
|
'ctrl_mode', default=self._ctrl_mode # type: ignore
|
||||||
): vol.In(self._miot_i18n.translate(key='config.control_mode')),
|
): vol.In(self._miot_i18n.translate(key='config.control_mode')),
|
||||||
@ -1314,6 +1281,52 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
|
|||||||
self, user_input: Optional[dict] = None
|
self, user_input: Optional[dict] = None
|
||||||
):
|
):
|
||||||
if user_input:
|
if user_input:
|
||||||
|
# Room filter
|
||||||
|
include_items: dict = {}
|
||||||
|
exclude_items: dict = {}
|
||||||
|
room_list_in: list = user_input.get('room_list', [])
|
||||||
|
if room_list_in:
|
||||||
|
if user_input.get(
|
||||||
|
'room_filter_mode', 'include') == 'include':
|
||||||
|
include_items['room_id'] = room_list_in
|
||||||
|
else:
|
||||||
|
exclude_items['room_id'] = room_list_in
|
||||||
|
# Connect Type filter
|
||||||
|
type_list_in: list = user_input.get('type_list', [])
|
||||||
|
if type_list_in:
|
||||||
|
if user_input.get(
|
||||||
|
'type_filter_mode', 'include') == 'include':
|
||||||
|
include_items['connect_type'] = type_list_in
|
||||||
|
else:
|
||||||
|
exclude_items['connect_type'] = type_list_in
|
||||||
|
# Model filter
|
||||||
|
model_list_in: list = user_input.get('model_list', [])
|
||||||
|
if model_list_in:
|
||||||
|
if user_input.get(
|
||||||
|
'model_filter_mode', 'include') == 'include':
|
||||||
|
include_items['model'] = model_list_in
|
||||||
|
else:
|
||||||
|
exclude_items['model'] = model_list_in
|
||||||
|
# Device filter
|
||||||
|
device_list_in: list = user_input.get('device_list', [])
|
||||||
|
if device_list_in:
|
||||||
|
if user_input.get(
|
||||||
|
'devices_filter_mode', 'include') == 'include':
|
||||||
|
include_items['did'] = device_list_in
|
||||||
|
else:
|
||||||
|
exclude_items['did'] = device_list_in
|
||||||
|
device_filter_list = _handle_devices_filter(
|
||||||
|
devices=self._device_list_sorted,
|
||||||
|
logic_or=(user_input.get('statistics_logic', 'or') == 'or'),
|
||||||
|
item_in=include_items, item_ex=exclude_items)
|
||||||
|
if not device_filter_list:
|
||||||
|
raise AbortFlow(
|
||||||
|
reason='config_flow_error',
|
||||||
|
description_placeholders={
|
||||||
|
'error': 'invalid devices_filter'})
|
||||||
|
self._device_list_sorted = dict(sorted(
|
||||||
|
device_filter_list.items(), key=lambda item:
|
||||||
|
item[1].get('home_id', '')+item[1].get('room_id', '')))
|
||||||
return await self.update_devices_done_async()
|
return await self.update_devices_done_async()
|
||||||
return await self.__display_devices_filter_form(reason='')
|
return await self.__display_devices_filter_form(reason='')
|
||||||
|
|
||||||
@ -1388,6 +1401,8 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
|
|||||||
): vol.In(trans_statistics_logic),
|
): vol.In(trans_statistics_logic),
|
||||||
}),
|
}),
|
||||||
errors={'base': reason},
|
errors={'base': reason},
|
||||||
|
description_placeholders={
|
||||||
|
'devices_count': str(len(self._device_list_sorted))},
|
||||||
last_step=False
|
last_step=False
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1598,6 +1613,7 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
|
|||||||
|
|
||||||
|
|
||||||
async def handle_oauth_webhook(hass, webhook_id, request):
|
async def handle_oauth_webhook(hass, webhook_id, request):
|
||||||
|
"""Webhook to handle oauth2 callback."""
|
||||||
# pylint: disable=inconsistent-quotes
|
# pylint: disable=inconsistent-quotes
|
||||||
try:
|
try:
|
||||||
data = dict(request.query)
|
data = dict(request.query)
|
||||||
@ -1623,3 +1639,38 @@ async def handle_oauth_webhook(hass, webhook_id, request):
|
|||||||
return web.Response(
|
return web.Response(
|
||||||
body=oauth_redirect_page(hass.config.language, 'fail'),
|
body=oauth_redirect_page(hass.config.language, 'fail'),
|
||||||
content_type='text/html')
|
content_type='text/html')
|
||||||
|
|
||||||
|
|
||||||
|
def _handle_devices_filter(
|
||||||
|
devices: dict, logic_or: bool, item_in: dict, item_ex: dict
|
||||||
|
) -> dict:
|
||||||
|
"""Private method to filter devices."""
|
||||||
|
include_set: Set = set([])
|
||||||
|
if not item_in:
|
||||||
|
include_set = set(devices.keys())
|
||||||
|
else:
|
||||||
|
filter_item: list[set] = []
|
||||||
|
for key, value in item_in.items():
|
||||||
|
filter_item.append(set([
|
||||||
|
did for did, info in devices.items()
|
||||||
|
if str(info[key]) in value]))
|
||||||
|
include_set = (
|
||||||
|
set.union(*filter_item)
|
||||||
|
if logic_or else set.intersection(*filter_item))
|
||||||
|
if not include_set:
|
||||||
|
return {}
|
||||||
|
if item_ex:
|
||||||
|
filter_item: list[set] = []
|
||||||
|
for key, value in item_ex.items():
|
||||||
|
filter_item.append(set([
|
||||||
|
did for did, info in devices.items()
|
||||||
|
if str(info[key]) in value]))
|
||||||
|
exclude_set: Set = (
|
||||||
|
set.union(*filter_item)
|
||||||
|
if logic_or else set.intersection(*filter_item))
|
||||||
|
if exclude_set:
|
||||||
|
include_set = include_set-exclude_set
|
||||||
|
if not include_set:
|
||||||
|
return {}
|
||||||
|
return {
|
||||||
|
did: info for did, info in devices.items() if did in include_set}
|
||||||
|
|||||||
@ -43,7 +43,7 @@
|
|||||||
},
|
},
|
||||||
"devices_filter": {
|
"devices_filter": {
|
||||||
"title": "筛选设备",
|
"title": "筛选设备",
|
||||||
"description": "## 使用介绍\r\n支持按照房间名称、设备接入类型、设备型号筛选设备,同时也支持设备维度筛选。\r\n- 统计优先级:排除优先级高于包含优先级,会先取包含项,然后再排除。\r\n- 筛选优先级:筛选设备>筛选设备型号>筛选设备接入类型>筛选家庭房间\r\n### 统计逻辑\r\n- 与逻辑:取所有同模式筛选项的交集。\r\n- 或逻辑:取所有同模式筛选项的并集。\r\n### 筛选模式\r\n- 排除:移除不需要的项。\r\n- 包含:包含需要的项。\r\n- 您也可以进入对应集成项【配置>更新设备列表】页面重新筛选。",
|
"description": "## 使用介绍\r\n支持按照房间名称、设备接入类型、设备型号筛选设备,同时也支持设备维度筛选。\r\n- 统计优先级:排除优先级高于包含优先级,会先取包含项,然后再排除。\r\n- 筛选优先级:筛选设备>筛选设备型号>筛选设备接入类型>筛选家庭房间\r\n### 统计逻辑\r\n- 与逻辑:取所有同模式筛选项的交集。\r\n- 或逻辑:取所有同模式筛选项的并集。\r\n### 筛选模式\r\n- 排除:移除不需要的项。\r\n- 包含:包含需要的项。\r\n\r\n您也可以进入对应集成项【配置>更新设备列表】页面重新筛选。",
|
||||||
"data": {
|
"data": {
|
||||||
"statistics_logic": "统计逻辑",
|
"statistics_logic": "统计逻辑",
|
||||||
"room_filter_mode": "筛选家庭房间",
|
"room_filter_mode": "筛选家庭房间",
|
||||||
@ -121,7 +121,7 @@
|
|||||||
},
|
},
|
||||||
"devices_filter": {
|
"devices_filter": {
|
||||||
"title": "筛选设备",
|
"title": "筛选设备",
|
||||||
"description": "## 使用介绍\r\n支持按照房间名称、设备接入类型、设备型号筛选设备,同时也支持设备维度筛选。\r\n- 统计优先级:排除优先级高于包含优先级,会先取包含项,然后再排除。\r\n- 筛选优先级:筛选设备>筛选设备型号>筛选设备接入类型>筛选家庭房间\r\n### 统计逻辑\r\n- 与逻辑:取所有同模式筛选项的交集。\r\n- 或逻辑:取所有同模式筛选项的并集。\r\n### 筛选模式\r\n- 排除:移除不需要的项。\r\n- 包含:包含需要的项。\r\n- 您也可以进入对应集成项【配置>更新设备列表】页面重新筛选。",
|
"description": "## 使用介绍\r\n支持按照房间名称、设备接入类型、设备型号筛选设备,同时也支持设备维度筛选。\r\n- 统计优先级:排除优先级高于包含优先级,会先取包含项,然后再排除。\r\n- 筛选优先级:筛选设备>筛选设备型号>筛选设备接入类型>筛选家庭房间\r\n### 统计逻辑\r\n- 与逻辑:取所有同模式筛选项的交集。\r\n- 或逻辑:取所有同模式筛选项的并集。\r\n### 筛选模式\r\n- 排除:移除不需要的项。\r\n- 包含:包含需要的项。\r\n\r\n您也可以进入对应集成项【配置>更新设备列表】页面重新筛选。",
|
||||||
"data": {
|
"data": {
|
||||||
"statistics_logic": "统计逻辑",
|
"statistics_logic": "统计逻辑",
|
||||||
"room_filter_mode": "筛选家庭房间",
|
"room_filter_mode": "筛选家庭房间",
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user