Home Assistant Unofficial Reference 2024.12.1
discovery.py
Go to the documentation of this file.
1 """Deal with Cast discovery."""
2 
3 import logging
4 import threading
5 
6 import pychromecast
7 
8 from homeassistant.config_entries import ConfigEntry
9 from homeassistant.const import EVENT_HOMEASSISTANT_STOP
10 from homeassistant.core import HomeAssistant
11 from homeassistant.helpers.dispatcher import dispatcher_send
12 
13 from .const import (
14  CAST_BROWSER_KEY,
15  CONF_KNOWN_HOSTS,
16  INTERNAL_DISCOVERY_RUNNING_KEY,
17  SIGNAL_CAST_DISCOVERED,
18  SIGNAL_CAST_REMOVED,
19 )
20 from .helpers import ChromecastInfo, ChromeCastZeroconf
21 
22 _LOGGER = logging.getLogger(__name__)
23 
24 
26  hass: HomeAssistant, cast_info: pychromecast.models.CastInfo
27 ) -> None:
28  """Discover a Chromecast."""
29 
30  info = ChromecastInfo(
31  cast_info=cast_info,
32  )
33 
34  if info.uuid is None:
35  _LOGGER.error("Discovered chromecast without uuid %s", info)
36  return
37 
38  info = info.fill_out_missing_chromecast_info(hass)
39  _LOGGER.debug("Discovered new or updated chromecast %s", info)
40 
41  dispatcher_send(hass, SIGNAL_CAST_DISCOVERED, info)
42 
43 
44 def _remove_chromecast(hass: HomeAssistant, info: ChromecastInfo) -> None:
45  # Removed chromecast
46  _LOGGER.debug("Removed chromecast %s", info)
47 
48  dispatcher_send(hass, SIGNAL_CAST_REMOVED, info)
49 
50 
51 def setup_internal_discovery(hass: HomeAssistant, config_entry: ConfigEntry) -> None:
52  """Set up the pychromecast internal discovery."""
53  if INTERNAL_DISCOVERY_RUNNING_KEY not in hass.data:
54  hass.data[INTERNAL_DISCOVERY_RUNNING_KEY] = threading.Lock()
55 
56  if not hass.data[INTERNAL_DISCOVERY_RUNNING_KEY].acquire(blocking=False):
57  # Internal discovery is already running
58  return
59 
60  class CastListener(pychromecast.discovery.AbstractCastListener):
61  """Listener for discovering chromecasts."""
62 
63  def add_cast(self, uuid, _):
64  """Handle zeroconf discovery of a new chromecast."""
65  discover_chromecast(hass, browser.devices[uuid])
66 
67  def update_cast(self, uuid, _):
68  """Handle zeroconf discovery of an updated chromecast."""
69  discover_chromecast(hass, browser.devices[uuid])
70 
71  def remove_cast(self, uuid, service, cast_info):
72  """Handle zeroconf discovery of a removed chromecast."""
74  hass,
76  cast_info=cast_info,
77  ),
78  )
79 
80  _LOGGER.debug("Starting internal pychromecast discovery")
81  browser = pychromecast.discovery.CastBrowser(
82  CastListener(),
83  ChromeCastZeroconf.get_zeroconf(),
84  config_entry.data.get(CONF_KNOWN_HOSTS),
85  )
86  hass.data[CAST_BROWSER_KEY] = browser
87  browser.start_discovery()
88 
89  def stop_discovery(event):
90  """Stop discovery of new chromecasts."""
91  _LOGGER.debug("Stopping internal pychromecast discovery")
92  browser.stop_discovery()
93  hass.data[INTERNAL_DISCOVERY_RUNNING_KEY].release()
94 
95  hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, stop_discovery)
96 
97  config_entry.add_update_listener(config_entry_updated)
98 
99 
100 async def config_entry_updated(hass: HomeAssistant, config_entry: ConfigEntry) -> None:
101  """Handle config entry being updated."""
102  browser = hass.data[CAST_BROWSER_KEY]
103  browser.host_browser.update_hosts(config_entry.data.get(CONF_KNOWN_HOSTS))
None discover_chromecast(HomeAssistant hass, pychromecast.models.CastInfo cast_info)
Definition: discovery.py:27
None setup_internal_discovery(HomeAssistant hass, ConfigEntry config_entry)
Definition: discovery.py:51
None config_entry_updated(HomeAssistant hass, ConfigEntry config_entry)
Definition: discovery.py:100
None _remove_chromecast(HomeAssistant hass, ChromecastInfo info)
Definition: discovery.py:44
None dispatcher_send(HomeAssistant hass, str signal, *Any args)
Definition: dispatcher.py:137