def _schedule_add_entities(self, new_entities, update_before_add=False):
     """Synchronously schedule adding entities for a single platform."""
     run_callback_threadsafe(
         self.hass.loop,
         self._async_schedule_add_entities, list(new_entities),
         update_before_add
     ).result()
def listen(hass, service, callback):
    """Set up listener for discovery of specific service.

    Service can be a string or a list/tuple.
    """
    run_callback_threadsafe(
        hass.loop, async_listen, hass, service, callback).result()
    def test_get_clientsession_with_ssl(self):
        """Test init clientsession with ssl."""
        run_callback_threadsafe(self.hass.loop, client.async_get_clientsession,
                                self.hass).result()

        assert isinstance(
            self.hass.data[client.DATA_CLIENTSESSION], aiohttp.ClientSession)
        assert isinstance(
            self.hass.data[client.DATA_CONNECTOR], aiohttp.TCPConnector)
Exemple #4
0
    def register(self, domain, service, service_func, schema=None):
        """
        Register a service.

        Schema is called to coerce and validate the service data.
        """
        run_callback_threadsafe(
            self._hass.loop,
            self.async_register, domain, service, service_func, schema
        ).result()
Exemple #5
0
    def register(self, domain: str, service: str, service_func: Callable,
                 schema: Optional[vol.Schema] = None) -> None:
        """
        Register a service.

        Schema is called to coerce and validate the service data.
        """
        run_callback_threadsafe(
            self._hass.loop,
            self.async_register, domain, service, service_func, schema
        ).result()
Exemple #6
0
    def set(self, entity_id, new_state, attributes=None, force_update=False):
        """Set the state of an entity, add entity if it does not exist.

        Attributes is an optional dict to specify attributes of this state.

        If you just update the attributes and not the state, last changed will
        not be affected.
        """
        run_callback_threadsafe(
            self._loop,
            self.async_set, entity_id, new_state, attributes, force_update,
        ).result()
Exemple #7
0
def setup_and_run_hass(config_dir: str,
                       args: argparse.Namespace) -> Optional[int]:
    """Set up HASS and run."""
    from homeassistant import bootstrap

    # Run a simple daemon runner process on Windows to handle restarts
    if os.name == 'nt' and '--runner' not in sys.argv:
        nt_args = cmdline() + ['--runner']
        while True:
            try:
                subprocess.check_call(nt_args)
                sys.exit(0)
            except subprocess.CalledProcessError as exc:
                if exc.returncode != RESTART_EXIT_CODE:
                    sys.exit(exc.returncode)

    if args.demo_mode:
        config = {
            'frontend': {},
            'demo': {}
        }
        hass = bootstrap.from_config_dict(
            config, config_dir=config_dir, verbose=args.verbose,
            skip_pip=args.skip_pip, log_rotate_days=args.log_rotate_days,
            log_file=args.log_file, log_no_color=args.log_no_color)
    else:
        config_file = ensure_config_file(config_dir)
        print('Config directory:', config_dir)
        hass = bootstrap.from_config_file(
            config_file, verbose=args.verbose, skip_pip=args.skip_pip,
            log_rotate_days=args.log_rotate_days, log_file=args.log_file,
            log_no_color=args.log_no_color)

    if hass is None:
        return None

    if args.open_ui:
        # Imported here to avoid importing asyncio before monkey patch
        from homeassistant.util.async_ import run_callback_threadsafe

        def open_browser(event):
            """Open the webinterface in a browser."""
            if hass.config.api is not None:
                import webbrowser
                webbrowser.open(hass.config.api.base_url)

        run_callback_threadsafe(
            hass.loop,
            hass.bus.async_listen_once,
            EVENT_HOMEASSISTANT_START, open_browser
        )

    return hass.start()
 def test_update_template_error(self, mock_render):
     """Test the template update error."""
     vs = run_callback_threadsafe(
         self.hass.loop, template.BinarySensorTemplate,
         self.hass, 'parent', 'Parent', 'motion',
         template_hlpr.Template('{{ 1 > 1 }}', self.hass),
         None, None, MATCH_ALL, None, None
     ).result()
     mock_render.side_effect = TemplateError('foo')
     run_callback_threadsafe(self.hass.loop, vs.async_check_state).result()
     mock_render.side_effect = TemplateError(
         "UndefinedError: 'None' has no attribute")
     run_callback_threadsafe(self.hass.loop, vs.async_check_state).result()
    def test_get_clientsession_cleanup(self):
        """Test init clientsession with ssl."""
        run_callback_threadsafe(self.hass.loop, client.async_get_clientsession,
                                self.hass).result()

        assert isinstance(
            self.hass.data[client.DATA_CLIENTSESSION], aiohttp.ClientSession)
        assert isinstance(
            self.hass.data[client.DATA_CONNECTOR], aiohttp.TCPConnector)

        self.hass.bus.fire(EVENT_HOMEASSISTANT_CLOSE)
        self.hass.block_till_done()

        assert self.hass.data[client.DATA_CLIENTSESSION].closed
        assert self.hass.data[client.DATA_CONNECTOR].closed
def numeric_state(hass: HomeAssistant, entity, below=None, above=None,
                  value_template=None, variables=None):
    """Test a numeric state condition."""
    return run_callback_threadsafe(
        hass.loop, async_numeric_state, hass, entity, below, above,
        value_template, variables,
    ).result()
Exemple #11
0
    def remove(self, entity_id: str) -> bool:
        """Remove the state of an entity.

        Returns boolean to indicate if an entity was removed.
        """
        return run_callback_threadsafe(  # type: ignore
            self._loop, self.async_remove, entity_id).result()
    def render(self, variables=None, **kwargs):
        """Render given template."""
        if variables is not None:
            kwargs.update(variables)

        return run_callback_threadsafe(
            self.hass.loop, self.async_render, kwargs).result()
Exemple #13
0
def request_config(hass, *args, **kwargs):
    """Create a new request for configuration.

    Will return an ID to be used for sequent calls.
    """
    return run_callback_threadsafe(
        hass.loop, ft.partial(async_request_config, hass, *args, **kwargs)
    ).result()
Exemple #14
0
 def target_callback(self, fail=False, invalid=False):
     """Run add callback in the event loop."""
     future = hasync.run_callback_threadsafe(
         self.loop, self.add_callback, 1, 2, fail, invalid)
     try:
         return future.result()
     finally:
         future.done() or future.cancel()
    def render_with_possible_json_value(self, value, error_value=_SENTINEL):
        """Render template with value exposed.

        If valid JSON will expose value_json too.
        """
        return run_callback_threadsafe(
            self.hass.loop, self.async_render_with_possible_json_value, value,
            error_value).result()
Exemple #16
0
def numeric_state(hass: HomeAssistant, entity: Union[None, str, State],
                  below: Optional[float] = None, above: Optional[float] = None,
                  value_template: Optional[Template] = None,
                  variables: TemplateVarsType = None) -> bool:
    """Test a numeric state condition."""
    return cast(bool, run_callback_threadsafe(
        hass.loop, async_numeric_state, hass, entity, below, above,
        value_template, variables,
    ).result())
def dispatcher_connect(hass, signal, target):
    """Connect a callable function to a signal."""
    async_unsub = run_callback_threadsafe(
        hass.loop, async_dispatcher_connect, hass, signal, target).result()

    def remove_dispatcher():
        """Remove signal listener."""
        run_callback_threadsafe(hass.loop, async_unsub).result()

    return remove_dispatcher
async def setup_and_run_hass(config_dir: str,
                             args: argparse.Namespace) -> int:
    """Set up HASS and run."""
    # pylint: disable=redefined-outer-name
    from homeassistant import bootstrap, core

    hass = core.HomeAssistant()

    if args.demo_mode:
        config = {
            'frontend': {},
            'demo': {}
        }  # type: Dict[str, Any]
        bootstrap.async_from_config_dict(
            config, hass, config_dir=config_dir, verbose=args.verbose,
            skip_pip=args.skip_pip, log_rotate_days=args.log_rotate_days,
            log_file=args.log_file, log_no_color=args.log_no_color)
    else:
        config_file = await ensure_config_file(hass, config_dir)
        print('Config directory:', config_dir)
        await bootstrap.async_from_config_file(
            config_file, hass, verbose=args.verbose, skip_pip=args.skip_pip,
            log_rotate_days=args.log_rotate_days, log_file=args.log_file,
            log_no_color=args.log_no_color)

    if args.open_ui:
        # Imported here to avoid importing asyncio before monkey patch
        from homeassistant.util.async_ import run_callback_threadsafe

        def open_browser(_: Any) -> None:
            """Open the web interface in a browser."""
            if hass.config.api is not None:
                import webbrowser
                webbrowser.open(hass.config.api.base_url)

        run_callback_threadsafe(
            hass.loop,
            hass.bus.async_listen_once,
            EVENT_HOMEASSISTANT_START, open_browser
        )

    return await hass.async_run()
    def test_attributes(self):
        """Test the attributes."""
        vs = run_callback_threadsafe(
            self.hass.loop, template.BinarySensorTemplate,
            self.hass, 'parent', 'Parent', 'motion',
            template_hlpr.Template('{{ 1 > 1 }}', self.hass),
            None, None, MATCH_ALL, None, None
        ).result()
        assert not vs.should_poll
        assert 'motion' == vs.device_class
        assert 'Parent' == vs.name

        run_callback_threadsafe(self.hass.loop, vs.async_check_state).result()
        assert not vs.is_on

        # pylint: disable=protected-access
        vs._template = template_hlpr.Template("{{ 2 > 1 }}", self.hass)

        run_callback_threadsafe(self.hass.loop, vs.async_check_state).result()
        assert vs.is_on
Exemple #20
0
def dispatcher_connect(hass: HomeAssistantType, signal: str,
                       target: Callable[..., None]) -> Callable[[], None]:
    """Connect a callable function to a signal."""
    async_unsub = run_callback_threadsafe(
        hass.loop, async_dispatcher_connect, hass, signal, target).result()

    def remove_dispatcher() -> None:
        """Remove signal listener."""
        run_callback_threadsafe(hass.loop, async_unsub).result()

    return remove_dispatcher
Exemple #21
0
    def listen(self, event_type, listener):
        """Listen for all events or events of a specific type.

        To listen to all events specify the constant ``MATCH_ALL``
        as event_type.
        """
        async_remove_listener = run_callback_threadsafe(
            self._hass.loop, self.async_listen, event_type, listener).result()

        def remove_listener():
            """Remove the listener."""
            run_callback_threadsafe(
                self._hass.loop, async_remove_listener).result()

        return remove_listener
Exemple #22
0
def generate_entity_id(entity_id_format: str, name: Optional[str],
                       current_ids: Optional[List[str]] = None,
                       hass: Optional[HomeAssistant] = None) -> str:
    """Generate a unique entity ID based on given entity IDs or used IDs."""
    if current_ids is None:
        if hass is None:
            raise ValueError("Missing required parameter currentids or hass")
        return run_callback_threadsafe(
            hass.loop, async_generate_entity_id, entity_id_format, name,
            current_ids, hass
        ).result()

    name = (slugify(name) or slugify(DEVICE_DEFAULT_NAME)).lower()

    return ensure_unique_string(
        entity_id_format.format(name), current_ids)
    def test_create_clientsession_with_ssl_and_cookies(self):
        """Test create clientsession with ssl."""
        def _async_helper():
            return client.async_create_clientsession(
                self.hass,
                cookies={'bla': True}
            )

        session = run_callback_threadsafe(
            self.hass.loop,
            _async_helper,
        ).result()

        assert isinstance(
            session, aiohttp.ClientSession)
        assert isinstance(
            self.hass.data[client.DATA_CONNECTOR], aiohttp.TCPConnector)
Exemple #24
0
    def listen_once(self, event_type, listener):
        """Listen once for event of a specific type.

        To listen to all events specify the constant ``MATCH_ALL``
        as event_type.

        Returns function to unsubscribe the listener.
        """
        async_remove_listener = run_callback_threadsafe(
            self._hass.loop, self.async_listen_once, event_type, listener,
        ).result()

        def remove_listener():
            """Remove the listener."""
            run_callback_threadsafe(
                self._hass.loop, async_remove_listener).result()

        return remove_listener
Exemple #25
0
def test_run_callback_threadsafe_from_inside_event_loop(mock_ident, _):
    """Testing calling run_callback_threadsafe from inside an event loop."""
    callback = MagicMock()
    loop = MagicMock()

    loop._thread_ident = None
    mock_ident.return_value = 5
    hasync.run_callback_threadsafe(loop, callback)
    assert len(loop.call_soon_threadsafe.mock_calls) == 1

    loop._thread_ident = 5
    mock_ident.return_value = 5
    with pytest.raises(RuntimeError):
        hasync.run_callback_threadsafe(loop, callback)
    assert len(loop.call_soon_threadsafe.mock_calls) == 1

    loop._thread_ident = 1
    mock_ident.return_value = 5
    hasync.run_callback_threadsafe(loop, callback)
    assert len(loop.call_soon_threadsafe.mock_calls) == 2
Exemple #26
0
 def services(self) -> Dict[str, Dict[str, Service]]:
     """Return dictionary with per domain a list of available services."""
     return run_callback_threadsafe(  # type: ignore
         self._hass.loop, self.async_services).result()
Exemple #27
0
def active_zone(hass, latitude, longitude, radius=0):
    """Find the active zone for given latitude, longitude."""
    return run_callback_threadsafe(hass.loop, async_active_zone, hass,
                                   latitude, longitude, radius).result()
 def condition_if(hass, variables=None):
     """Validate condition."""
     return run_callback_threadsafe(
         hass.loop, async_check, hass, variables,
     ).result()
Exemple #29
0
    def _determine_interval(self) -> int:
        """Calculate new interval between two API fetch (in minutes)."""
        intervals = {"default": self._max_interval}
        for device in self._devices.values():
            # Max interval if no location
            if device.location is None:
                continue

            current_zone = run_callback_threadsafe(
                self.hass.loop,
                async_active_zone,
                self.hass,
                device.location[DEVICE_LOCATION_LATITUDE],
                device.location[DEVICE_LOCATION_LONGITUDE],
                device.location[DEVICE_LOCATION_HORIZONTAL_ACCURACY],
            ).result()

            # Max interval if in zone
            if current_zone is not None:
                continue

            zones = (
                self.hass.states.get(entity_id)
                for entity_id in sorted(self.hass.states.entity_ids("zone")))

            distances = []
            for zone_state in zones:
                zone_state_lat = zone_state.attributes[
                    DEVICE_LOCATION_LATITUDE]
                zone_state_long = zone_state.attributes[
                    DEVICE_LOCATION_LONGITUDE]
                zone_distance = distance(
                    device.location[DEVICE_LOCATION_LATITUDE],
                    device.location[DEVICE_LOCATION_LONGITUDE],
                    zone_state_lat,
                    zone_state_long,
                )
                distances.append(round(zone_distance / 1000, 1))

            # Max interval if no zone
            if not distances:
                continue
            mindistance = min(distances)

            # Calculate out how long it would take for the device to drive
            # to the nearest zone at 120 km/h:
            interval = round(mindistance / 2, 0)

            # Never poll more than once per minute
            interval = max(interval, 1)

            if interval > 180:
                # Three hour drive?
                # This is far enough that they might be flying
                interval = self._max_interval

            if (device.battery_level is not None and device.battery_level <= 33
                    and mindistance > 3):
                # Low battery - let's check half as often
                interval = interval * 2

            intervals[device.name] = interval

        return max(
            int(min(intervals.items(), key=operator.itemgetter(1))[1]),
            self._max_interval,
        )
Exemple #30
0
def listen_platform(hass, component, callback):
    """Register a platform loader listener."""
    run_callback_threadsafe(hass.loop, async_listen_platform, hass, component,
                            callback).result()
Exemple #31
0
def listen_platform(hass: core.HomeAssistant, component: str,
                    callback: Callable) -> None:
    """Register a platform loader listener."""
    run_callback_threadsafe(hass.loop, async_listen_platform, hass, component,
                            callback).result()
Exemple #32
0
 def new_token_callback():
     """Update config entry with the new token."""
     run_callback_threadsafe(self.hass.loop, update_token_func, self._ws.token)
Exemple #33
0
def notify_errors(hass, request_id, error):
    """Add errors to a config request."""
    return run_callback_threadsafe(hass.loop, async_notify_errors, hass,
                                   request_id, error).result()
Exemple #34
0
def listen_platform(hass, component, callback):
    """Register a platform loader listener."""
    run_callback_threadsafe(
        hass.loop, async_listen_platform, hass, component, callback
    ).result()
Exemple #35
0
 def entity_ids(self, domain_filter: Optional[str] = None) -> List[str]:
     """List of entity ids that are being tracked."""
     future = run_callback_threadsafe(self._loop, self.async_entity_ids,
                                      domain_filter)
     return future.result()  # type: ignore
Exemple #36
0
 def listeners(self) -> Dict[str, int]:
     """Return dictionary with events and the number of listeners."""
     return run_callback_threadsafe(  # type: ignore
         self._hass.loop, self.async_listeners).result()
Exemple #37
0
 def remove(self, domain: str, service: str) -> None:
     """Remove a registered service from service handler."""
     run_callback_threadsafe(self._hass.loop, self.async_remove, domain,
                             service).result()
Exemple #38
0
 def stop(self) -> None:
     """Stop running script."""
     run_callback_threadsafe(self.hass.loop, self.async_stop).result()
Exemple #39
0
def template(hass: HomeAssistant,
             value_template: Template,
             variables: TemplateVarsType = None) -> bool:
    """Test if template condition matches."""
    return run_callback_threadsafe(hass.loop, async_template, hass,
                                   value_template, variables).result()
Exemple #40
0
 def remove():
     """Remove listener convert."""
     run_callback_threadsafe(hass.loop, async_remove).result()
Exemple #41
0
 def process_tags(self, tags):
     """Send event with detected tags and store data."""
     run_callback_threadsafe(self.hass.loop, self.async_process_tags,
                             tags).result()
Exemple #42
0
 def listeners(self):
     """Return dictionary with events and the number of listeners."""
     return run_callback_threadsafe(self._hass.loop,
                                    self.async_listeners).result()
 def _do_nothing(*_):
     run_callback_threadsafe(hass.loop, finish_event.set)
Exemple #44
0
 def remove_listener():
     """Remove the listener."""
     run_callback_threadsafe(self._hass.loop,
                             async_remove_listener).result()
Exemple #45
0
 def process_plates(self, plates, vehicles):
     """Send event with new plates and store data."""
     run_callback_threadsafe(self.hass.loop, self.async_process_plates,
                             plates, vehicles).result()
Exemple #46
0
 def remove():
     """Remove listener convert."""
     run_callback_threadsafe(hass.loop, async_remove).result()
Exemple #47
0
 def remove() -> None:
     """Threadsafe removal."""
     run_callback_threadsafe(hass.loop, async_remove).result()
 def process_plates(self, plates, vehicles):
     """Send event with new plates and store data."""
     run_callback_threadsafe(
         self.hass.loop, self.async_process_plates, plates, vehicles
     ).result()
def template(hass, value_template, variables=None):
    """Test if template condition matches."""
    return run_callback_threadsafe(
        hass.loop, async_template, hass, value_template, variables,
    ).result()
Exemple #50
0
 def threadsafe(*args, **kwargs):
     """Call func threadsafe."""
     hass = args[0]
     return run_callback_threadsafe(hass.loop,
                                    ft.partial(func, *args,
                                               **kwargs)).result()
Exemple #51
0
 def entity_ids(self, domain_filter=None):
     """List of entity ids that are being tracked."""
     future = run_callback_threadsafe(self._loop, self.async_entity_ids,
                                      domain_filter)
     return future.result()
 def remove_dispatcher() -> None:
     """Remove signal listener."""
     run_callback_threadsafe(hass.loop, async_unsub).result()
Exemple #53
0
 def all(self):
     """Create a list of all states."""
     return run_callback_threadsafe(self._loop, self.async_all).result()
Exemple #54
0
 def services(self):
     """Return dictionary with per domain a list of available services."""
     return run_callback_threadsafe(
         self._hass.loop,
         self.async_services,
     ).result()
Exemple #55
0
 def all(self) -> List[State]:
     """Create a list of all states."""
     return run_callback_threadsafe(  # type: ignore
         self._loop, self.async_all).result()
Exemple #56
0
def request_done(hass, request_id):
    """Mark a configuration request as done."""
    return run_callback_threadsafe(hass.loop, async_request_done, hass,
                                   request_id).result()
Exemple #57
0
def request_done(hass, request_id):
    """Mark a configuration request as done."""
    return run_callback_threadsafe(
        hass.loop, async_request_done, hass, request_id
    ).result()
Exemple #58
0
 def _schedule_add_entities(self, new_entities, update_before_add=False):
     """Schedule adding entities for a single platform, synchronously."""
     run_callback_threadsafe(self.hass.loop,
                             self._async_schedule_add_entities,
                             list(new_entities),
                             update_before_add).result()
Exemple #59
0
def notify_errors(hass, request_id, error):
    """Add errors to a config request."""
    return run_callback_threadsafe(
        hass.loop, async_notify_errors, hass, request_id, error
    ).result()
Exemple #60
0
 def process_faces(self, faces, total):
     """Send event with detected faces and store data."""
     run_callback_threadsafe(self.hass.loop, self.async_process_faces,
                             faces, total).result()