22
33from __future__ import annotations
44
5+ from collections .abc import Callable
56from dataclasses import dataclass
6-
7- from pyezvizapi .constants import DeviceSwitchType , SoundMode
7+ from typing import cast
8+
9+ from pyezvizapi .constants import (
10+ BatteryCameraWorkMode ,
11+ DeviceCatagories ,
12+ DeviceSwitchType ,
13+ SoundMode ,
14+ SupportExt ,
15+ )
816from pyezvizapi .exceptions import HTTPError , PyEzvizError
917
1018from homeassistant .components .select import SelectEntity , SelectEntityDescription
@@ -24,17 +32,83 @@ class EzvizSelectEntityDescription(SelectEntityDescription):
2432 """Describe a EZVIZ Select entity."""
2533
2634 supported_switch : int
35+ current_option : Callable [[EzvizSelect ], str | None ]
36+ select_option : Callable [[EzvizSelect , str , str ], None ]
37+
38+
39+ def alarm_sound_mode_current_option (ezvizSelect : EzvizSelect ) -> str | None :
40+ """Return the selected entity option to represent the entity state."""
41+ sound_mode_value = getattr (
42+ SoundMode , ezvizSelect .data [ezvizSelect .entity_description .key ]
43+ ).value
44+ if sound_mode_value in [0 , 1 , 2 ]:
45+ return ezvizSelect .options [sound_mode_value ]
46+
47+ return None
48+
49+
50+ def alarm_sound_mode_select_option (
51+ ezvizSelect : EzvizSelect , serial : str , option : str
52+ ) -> None :
53+ """Change the selected option."""
54+ sound_mode_value = ezvizSelect .options .index (option )
55+ ezvizSelect .coordinator .ezviz_client .alarm_sound (serial , sound_mode_value , 1 )
2756
2857
29- SELECT_TYPE = EzvizSelectEntityDescription (
58+ ALARM_SOUND_MODE_SELECT_TYPE = EzvizSelectEntityDescription (
3059 key = "alarm_sound_mod" ,
3160 translation_key = "alarm_sound_mode" ,
3261 entity_category = EntityCategory .CONFIG ,
3362 options = ["soft" , "intensive" , "silent" ],
3463 supported_switch = DeviceSwitchType .ALARM_TONE .value ,
64+ current_option = alarm_sound_mode_current_option ,
65+ select_option = alarm_sound_mode_select_option ,
3566)
3667
3768
69+ def battery_work_mode_current_option (ezvizSelect : EzvizSelect ) -> str | None :
70+ """Return the selected entity option to represent the entity state."""
71+ battery_work_mode = getattr (
72+ BatteryCameraWorkMode ,
73+ ezvizSelect .data [ezvizSelect .entity_description .key ],
74+ BatteryCameraWorkMode .UNKNOWN ,
75+ )
76+ if battery_work_mode == BatteryCameraWorkMode .UNKNOWN :
77+ return None
78+
79+ return battery_work_mode .name .lower ()
80+
81+
82+ def battery_work_mode_select_option (
83+ ezvizSelect : EzvizSelect , serial : str , option : str
84+ ) -> None :
85+ """Change the selected option."""
86+ battery_work_mode = getattr (BatteryCameraWorkMode , option .upper ())
87+ ezvizSelect .coordinator .ezviz_client .set_battery_camera_work_mode (
88+ serial , battery_work_mode .value
89+ )
90+
91+
92+ BATTERY_WORK_MODE_SELECT_TYPE = EzvizSelectEntityDescription (
93+ key = "battery_camera_work_mode" ,
94+ translation_key = "battery_camera_work_mode" ,
95+ icon = "mdi:battery-sync" ,
96+ entity_category = EntityCategory .CONFIG ,
97+ options = [
98+ "plugged_in" ,
99+ "high_performance" ,
100+ "power_save" ,
101+ "super_power_save" ,
102+ "custom" ,
103+ ],
104+ supported_switch = - 1 ,
105+ current_option = battery_work_mode_current_option ,
106+ select_option = battery_work_mode_select_option ,
107+ )
108+
109+ SELECT_TYPES = [ALARM_SOUND_MODE_SELECT_TYPE , BATTERY_WORK_MODE_SELECT_TYPE ]
110+
111+
38112async def async_setup_entry (
39113 hass : HomeAssistant ,
40114 entry : EzvizConfigEntry ,
@@ -43,12 +117,26 @@ async def async_setup_entry(
43117 """Set up EZVIZ select entities based on a config entry."""
44118 coordinator = entry .runtime_data
45119
46- async_add_entities (
47- EzvizSelect (coordinator , camera )
120+ entities = [
121+ EzvizSelect (coordinator , camera , ALARM_SOUND_MODE_SELECT_TYPE )
48122 for camera in coordinator .data
49123 for switch in coordinator .data [camera ]["switches" ]
50- if switch == SELECT_TYPE .supported_switch
51- )
124+ if switch == ALARM_SOUND_MODE_SELECT_TYPE .supported_switch
125+ ]
126+
127+ for camera in coordinator .data :
128+ device_category = coordinator .data [camera ].get ("device_category" )
129+ supportExt = coordinator .data [camera ].get ("supportExt" )
130+ if (
131+ device_category == DeviceCatagories .BATTERY_CAMERA_DEVICE_CATEGORY .value
132+ and supportExt
133+ and str (SupportExt .SupportBatteryManage .value ) in supportExt
134+ ):
135+ entities .append (
136+ EzvizSelect (coordinator , camera , BATTERY_WORK_MODE_SELECT_TYPE )
137+ )
138+
139+ async_add_entities (entities )
52140
53141
54142class EzvizSelect (EzvizEntity , SelectEntity ):
@@ -58,31 +146,23 @@ def __init__(
58146 self ,
59147 coordinator : EzvizDataUpdateCoordinator ,
60148 serial : str ,
149+ description : EzvizSelectEntityDescription ,
61150 ) -> None :
62- """Initialize the sensor ."""
151+ """Initialize the select entity ."""
63152 super ().__init__ (coordinator , serial )
64- self ._attr_unique_id = f"{ serial } _{ SELECT_TYPE .key } "
65- self .entity_description = SELECT_TYPE
153+ self ._attr_unique_id = f"{ serial } _{ description .key } "
154+ self .entity_description = description
66155
67156 @property
68157 def current_option (self ) -> str | None :
69158 """Return the selected entity option to represent the entity state."""
70- sound_mode_value = getattr (
71- SoundMode , self .data [self .entity_description .key ]
72- ).value
73- if sound_mode_value in [0 , 1 , 2 ]:
74- return self .options [sound_mode_value ]
75-
76- return None
159+ desc = cast (EzvizSelectEntityDescription , self .entity_description )
160+ return desc .current_option (self )
77161
78162 def select_option (self , option : str ) -> None :
79163 """Change the selected option."""
80- sound_mode_value = self .options .index (option )
81-
164+ desc = cast (EzvizSelectEntityDescription , self .entity_description )
82165 try :
83- self .coordinator .ezviz_client .alarm_sound (self ._serial , sound_mode_value , 1 )
84-
166+ return desc .select_option (self , self ._serial , option )
85167 except (HTTPError , PyEzvizError ) as err :
86- raise HomeAssistantError (
87- f"Cannot set Warning sound level for { self .entity_id } "
88- ) from err
168+ raise HomeAssistantError (f"Cannot select option for { desc .key } " ) from err
0 commit comments