1 """Class to hold remote accessories."""
3 from abc
import ABC, abstractmethod
7 from pyhap.const
import CATEGORY_TELEVISION
12 ATTR_CURRENT_ACTIVITY,
13 DOMAIN
as REMOTE_DOMAIN,
18 ATTR_SUPPORTED_FEATURES,
25 from .accessories
import TYPES, HomeAccessory
29 CHAR_ACTIVE_IDENTIFIER,
31 CHAR_CURRENT_VISIBILITY_STATE,
33 CHAR_INPUT_SOURCE_TYPE,
37 CHAR_SLEEP_DISCOVER_MODE,
38 EVENT_HOMEKIT_TV_REMOTE_KEY_PRESSED,
55 from .util
import cleanup_name_for_homekit
61 _LOGGER = logging.getLogger(__name__)
67 3: KEY_PREVIOUS_TRACK,
81 """Generate a InputSelect accessory."""
85 required_feature: int,
89 category: int = CATEGORY_TELEVISION,
92 """Initialize a InputSelect accessory object."""
93 super().
__init__(*args, category=category, **kwargs)
96 features = state.attributes.get(ATTR_SUPPORTED_FEATURES, 0)
98 self._mapped_sources_list: list[str] = []
104 if features & required_feature:
106 if len(sources) > MAXIMUM_SOURCES:
108 "%s: Reached maximum number of sources (%s)",
112 self.
sourcessources = sources[:MAXIMUM_SOURCES]
117 serv_tv = self.
serv_tvserv_tv = self.add_preload_service(
118 SERV_TELEVISION, self.
chars_tvchars_tv
121 CHAR_REMOTE_KEY, setter_callback=self.
set_remote_keyset_remote_key
123 self.set_primary_service(serv_tv)
124 serv_tv.configure_char(CHAR_CONFIGURED_NAME, value=self.display_name)
125 serv_tv.configure_char(CHAR_SLEEP_DISCOVER_MODE, value=
True)
127 CHAR_ACTIVE, setter_callback=self.
set_on_offset_on_off
134 CHAR_ACTIVE_IDENTIFIER, setter_callback=self.
set_input_sourceset_input_source
136 for index, source
in enumerate(self.
sourcessources):
137 serv_input = self.add_preload_service(
138 SERV_INPUT_SOURCE, [CHAR_IDENTIFIER, CHAR_NAME], unique_id=source
140 serv_tv.add_linked_service(serv_input)
141 serv_input.configure_char(CHAR_CONFIGURED_NAME, value=source)
142 serv_input.configure_char(CHAR_NAME, value=source)
143 serv_input.configure_char(CHAR_IDENTIFIER, value=index)
144 serv_input.configure_char(CHAR_IS_CONFIGURED, value=
True)
145 input_type = 3
if "hdmi" in source.lower()
else 0
146 serv_input.configure_char(CHAR_INPUT_SOURCE_TYPE, value=input_type)
147 serv_input.configure_char(CHAR_CURRENT_VISIBILITY_STATE, value=
False)
148 _LOGGER.debug(
"%s: Added source %s", self.
entity_identity_id, source)
151 """Return a dict of sources mapped to their homekit safe name."""
152 source_list = state.attributes.get(self.
source_list_keysource_list_key, [])
153 if self._mapped_sources_list != source_list:
155 cleanup_name_for_homekit(source): source
for source
in source_list
160 """Return ordered source list while preserving order with duplicates removed.
162 Some integrations have duplicate sources in the source list
163 which will make the source list conflict as HomeKit requires
170 """Move switch state to value if call came from HomeKit."""
174 """Send input set value if call came from HomeKit."""
178 """Send remote key value if call came from HomeKit."""
182 """Update input state after state changed."""
186 source = new_state.attributes.get(self.
source_keysource_key)
187 source_name = cleanup_name_for_homekit(source)
188 _LOGGER.debug(
"%s: Set current input to %s", self.
entity_identity_id, source_name)
189 if source_name
in self.
sourcessources:
190 index = self.
sourcessources.index(source_name)
195 if source_name
in possible_sources:
196 index = possible_sources.index(source_name)
197 if index >= MAXIMUM_SOURCES:
199 "%s: Source %s and above are not supported",
205 "%s: Sources out of sync. Rebuilding Accessory",
211 "%s: Source %s does not exist the source list: %s",
219 @TYPES.register("ActivityRemote")
221 """Generate a Activity Remote accessory."""
224 """Initialize a Activity Remote accessory object."""
226 RemoteEntityFeature.ACTIVITY,
227 ATTR_CURRENT_ACTIVITY,
236 """Move switch state to value if call came from HomeKit."""
237 _LOGGER.debug(
'%s: Set switch state for "on_off" to %s', self.
entity_identity_id, value)
238 service = SERVICE_TURN_ON
if value
else SERVICE_TURN_OFF
239 params = {ATTR_ENTITY_ID: self.
entity_identity_id}
243 """Send input set value if call came from HomeKit."""
244 _LOGGER.debug(
"%s: Set current input to %s", self.
entity_identity_id, value)
246 params = {ATTR_ENTITY_ID: self.
entity_identity_id, ATTR_ACTIVITY: source}
250 """Send remote key value if call came from HomeKit."""
251 _LOGGER.debug(
"%s: Set remote key to %s", self.
entity_identity_id, value)
252 if (key_name := REMOTE_KEYS.get(value))
is None:
253 _LOGGER.warning(
"%s: Unhandled key press for %s", self.
entity_identity_id, value)
255 self.
hasshass.bus.async_fire(
256 EVENT_HOMEKIT_TV_REMOTE_KEY_PRESSED,
257 {ATTR_KEY_NAME: key_name, ATTR_ENTITY_ID: self.
entity_identity_id},
262 """Update Television remote state after state changed."""
263 current_state = new_state.state
265 hk_state = 1
if current_state == STATE_ON
else 0
266 _LOGGER.debug(
"%s: Set current active state to %s", self.
entity_identity_id, hk_state)
None async_call_service(self, str domain, str service, dict[str, Any]|None service_data, Any|None value=None)
None async_update_state(self, State new_state)
None set_input_source(self, int value)
None set_on_off(self, bool value)
None __init__(self, *Any args)
None async_update_state(self, State new_state)
None set_remote_key(self, int value)