示例#1
0
def discover(include_device_type: bool, timeout: int) -> None:
    devices = VizioAsync.discovery_zeroconf(timeout)

    data = []

    if devices:
        data = [{
            "IP": dev.ip,
            "Port": dev.port,
            "Model": dev.model,
            "Name": dev.name
        } for dev in devices]
    else:
        _LOGGER.info("Couldn't find any devices using zeroconf, trying SSDP")
        devices = VizioAsync.discovery_ssdp(timeout)
        if devices:
            data = [{
                "IP": dev.ip,
                "Model": dev.model,
                "Name": dev.name
            } for dev in devices]

    if devices:
        if include_device_type:
            for dev in data:
                dev["Guessed Device Type"] = guess_device_type(
                    dev["IP"], dev.get("Port"))

        _LOGGER.info("\n%s", tabulate(data, "keys"))
    else:
        _LOGGER.info("No Vizio devices discoverd.")
示例#2
0
    async def async_step_tv_apps(
        self, user_input: Dict[str, Any] = None
    ) -> Dict[str, Any]:
        """Handle app configuration to complete TV configuration."""
        if user_input is not None:
            if user_input.get(CONF_APPS_TO_INCLUDE_OR_EXCLUDE):
                # Update stored apps with user entry config keys
                self._apps[user_input[CONF_INCLUDE_OR_EXCLUDE].lower()] = user_input[
                    CONF_APPS_TO_INCLUDE_OR_EXCLUDE
                ].copy()

            return await self._create_entry_if_unique(self._data)

        return self.async_show_form(
            step_id="tv_apps",
            data_schema=vol.Schema(
                {
                    vol.Optional(
                        CONF_INCLUDE_OR_EXCLUDE, default=CONF_INCLUDE.title(),
                    ): vol.In([CONF_INCLUDE.title(), CONF_EXCLUDE.title()]),
                    vol.Optional(CONF_APPS_TO_INCLUDE_OR_EXCLUDE): cv.multi_select(
                        VizioAsync.get_apps_list()
                    ),
                }
            ),
        )
示例#3
0
def get_apps_list(vizio: VizioAsync, country: str = "all") -> None:
    apps = vizio.get_apps_list(country)
    if apps:
        table = tabulate([{"Name": app} for app in apps], headers="keys")
        _LOGGER.info("\n%s", table)
    else:
        _LOGGER.error("Couldn't get list of apps")
示例#4
0
async def async_setup_entry(
    hass: HomeAssistantType,
    config_entry: ConfigEntry,
    async_add_entities: Callable[[List[Entity], bool], None],
) -> None:
    """Set up a Vizio media player entry."""
    host = config_entry.data[CONF_HOST]
    token = config_entry.data.get(CONF_ACCESS_TOKEN)
    name = config_entry.data[CONF_NAME]
    device_class = config_entry.data[CONF_DEVICE_CLASS]

    # If config entry options not set up, set them up, otherwise assign values managed in options
    volume_step = config_entry.options.get(
        CONF_VOLUME_STEP,
        config_entry.data.get(CONF_VOLUME_STEP, DEFAULT_VOLUME_STEP))

    params = {}
    if not config_entry.options:
        params["options"] = {CONF_VOLUME_STEP: volume_step}
        include_or_exclude_key = next(
            (key for key in config_entry.data.get(CONF_APPS, {})
             if key in [CONF_INCLUDE, CONF_EXCLUDE]),
            None,
        )
        if include_or_exclude_key:
            params["options"][CONF_APPS] = {
                include_or_exclude_key:
                config_entry.data[CONF_APPS][include_or_exclude_key].copy()
            }

    if not config_entry.data.get(CONF_VOLUME_STEP):
        new_data = config_entry.data.copy()
        new_data.update({CONF_VOLUME_STEP: volume_step})
        params["data"] = new_data

    if params:
        hass.config_entries.async_update_entry(config_entry, **params)

    device = VizioAsync(
        DEVICE_ID,
        host,
        name,
        auth_token=token,
        device_type=VIZIO_DEVICE_CLASSES[device_class],
        session=async_get_clientsession(hass, False),
        timeout=DEFAULT_TIMEOUT,
    )

    if not await device.can_connect_with_auth_check():
        _LOGGER.warning("Failed to connect to %s", host)
        raise PlatformNotReady

    entity = VizioDevice(
        config_entry,
        device,
        name,
        device_class,
    )

    async_add_entities([entity], update_before_add=True)
示例#5
0
async def async_setup_entry(
    hass: HomeAssistant,
    config_entry: ConfigEntry,
    async_add_entities: AddEntitiesCallback,
) -> None:
    """Set up a Vizio media player entry."""
    host = config_entry.data[CONF_HOST]
    token = config_entry.data.get(CONF_ACCESS_TOKEN)
    name = config_entry.data[CONF_NAME]
    device_class = config_entry.data[CONF_DEVICE_CLASS]

    # If config entry options not set up, set them up, otherwise assign values managed in options
    volume_step = config_entry.options.get(
        CONF_VOLUME_STEP,
        config_entry.data.get(CONF_VOLUME_STEP, DEFAULT_VOLUME_STEP))

    params = {}
    if not config_entry.options:
        params["options"] = {CONF_VOLUME_STEP: volume_step}

        include_or_exclude_key = next(
            (key for key in config_entry.data.get(CONF_APPS, {})
             if key in (CONF_INCLUDE, CONF_EXCLUDE)),
            None,
        )
        if include_or_exclude_key:
            params["options"][CONF_APPS] = {
                include_or_exclude_key:
                config_entry.data[CONF_APPS][include_or_exclude_key].copy()
            }

    if not config_entry.data.get(CONF_VOLUME_STEP):
        new_data = config_entry.data.copy()
        new_data.update({CONF_VOLUME_STEP: volume_step})
        params["data"] = new_data

    if params:
        hass.config_entries.async_update_entry(config_entry, **params)

    device = VizioAsync(
        DEVICE_ID,
        host,
        name,
        auth_token=token,
        device_type=VIZIO_DEVICE_CLASSES[device_class],
        session=async_get_clientsession(hass, False),
        timeout=DEFAULT_TIMEOUT,
    )

    apps_coordinator = hass.data[DOMAIN].get(CONF_APPS)

    entity = VizioDevice(config_entry, device, name, device_class,
                         apps_coordinator)

    async_add_entities([entity], update_before_add=True)
    platform = entity_platform.async_get_current_platform()
    platform.async_register_entity_service(SERVICE_UPDATE_SETTING,
                                           UPDATE_SETTING_SCHEMA,
                                           "async_update_setting")
示例#6
0
    async def async_step_init(
        self, user_input: Dict[str, Any] = None
    ) -> Dict[str, Any]:
        """Manage the vizio options."""
        if user_input is not None:
            if user_input.get(CONF_APPS_TO_INCLUDE_OR_EXCLUDE):
                user_input[CONF_APPS] = {
                    user_input[CONF_INCLUDE_OR_EXCLUDE]: user_input[
                        CONF_APPS_TO_INCLUDE_OR_EXCLUDE
                    ].copy()
                }

                user_input.pop(CONF_INCLUDE_OR_EXCLUDE)
                user_input.pop(CONF_APPS_TO_INCLUDE_OR_EXCLUDE)

            return self.async_create_entry(title="", data=user_input)

        options = {
            vol.Optional(
                CONF_VOLUME_STEP,
                default=self.config_entry.options.get(
                    CONF_VOLUME_STEP, DEFAULT_VOLUME_STEP
                ),
            ): vol.All(vol.Coerce(int), vol.Range(min=1, max=10))
        }

        if self.config_entry.data[CONF_DEVICE_CLASS] == DEVICE_CLASS_TV:
            default_include_or_exclude = (
                CONF_EXCLUDE
                if self.config_entry.options
                and CONF_EXCLUDE in self.config_entry.options.get(CONF_APPS)
                else CONF_EXCLUDE
            )
            options.update(
                {
                    vol.Optional(
                        CONF_INCLUDE_OR_EXCLUDE,
                        default=default_include_or_exclude.title(),
                    ): vol.All(
                        vol.In([CONF_INCLUDE.title(), CONF_EXCLUDE.title()]), vol.Lower
                    ),
                    vol.Optional(
                        CONF_APPS_TO_INCLUDE_OR_EXCLUDE,
                        default=self.config_entry.options.get(CONF_APPS, {}).get(
                            default_include_or_exclude, []
                        ),
                    ): cv.multi_select(VizioAsync.get_apps_list()),
                }
            )

        return self.async_show_form(step_id="init", data_schema=vol.Schema(options))
示例#7
0
async def async_setup_entry(
    hass: HomeAssistantType,
    config_entry: ConfigEntry,
    async_add_entities: Callable[[List[Entity], bool], None],
) -> None:
    """Set up a Vizio media player entry."""
    host = config_entry.data[CONF_HOST]
    token = config_entry.data.get(CONF_ACCESS_TOKEN)
    name = config_entry.data[CONF_NAME]
    device_class = config_entry.data[CONF_DEVICE_CLASS]

    # If config entry options not set up, set them up, otherwise assign values managed in options
    if not config_entry.options:
        volume_step = config_entry.data.get(CONF_VOLUME_STEP,
                                            DEFAULT_VOLUME_STEP)
        hass.config_entries.async_update_entry(
            config_entry, options={CONF_VOLUME_STEP: volume_step})
    else:
        volume_step = config_entry.options[CONF_VOLUME_STEP]

    device = VizioAsync(
        DEVICE_ID,
        host,
        name,
        auth_token=token,
        device_type=VIZIO_DEVICE_CLASSES[device_class],
        session=async_get_clientsession(hass, False),
        timeout=DEFAULT_TIMEOUT,
    )

    if not await device.can_connect():
        fail_auth_msg = ""
        if token:
            fail_auth_msg = f"and auth token '{token}' are correct."
        else:
            fail_auth_msg = "is correct."
        _LOGGER.warning(
            "Failed to connect to Vizio device, please check if host '%s' "
            "is valid and available. Also check if device class '%s' %s",
            host,
            device_class,
            fail_auth_msg,
        )
        raise PlatformNotReady

    entity = VizioDevice(config_entry, device, name, volume_step, device_class)

    async_add_entities([entity], update_before_add=True)
示例#8
0
def discover(include_device_type: bool, timeout: int) -> None:
    devices = VizioAsync.discovery_zeroconf(timeout)

    if include_device_type:
        table = tabulate(
            [[
                dev.ip,
                dev.port,
                dev.model,
                dev.name,
                guess_device_type(dev.ip, dev.port),
            ] for dev in devices],
            headers=["IP", "Port", "Model", "Name", "Guessed Device Type"],
        )
    else:
        table = tabulate(
            [[dev.ip, dev.port, dev.model, dev.name] for dev in devices],
            headers=["IP", "Port", "Model", "Name"],
        )

    _LOGGER.info("\n%s", table)
示例#9
0
    async def async_step_pair_tv(
        self, user_input: Dict[str, Any] = None
    ) -> Dict[str, Any]:
        """Start pairing process and ask user for PIN to complete pairing process."""
        errors = {}

        # Start pairing process if it hasn't already started
        if not self._ch_type and not self._pairing_token:
            dev = VizioAsync(
                DEVICE_ID,
                self._data[CONF_HOST],
                self._data[CONF_NAME],
                None,
                self._data[CONF_DEVICE_CLASS],
                session=async_get_clientsession(self.hass, False),
            )
            pair_data = await dev.start_pair()

            if pair_data:
                self._ch_type = pair_data.ch_type
                self._pairing_token = pair_data.token
                return await self.async_step_pair_tv()

            return self.async_show_form(
                step_id="user",
                data_schema=_get_config_schema(self._data),
                errors={"base": "cant_connect"},
            )

        # Complete pairing process if PIN has been provided
        if user_input and user_input.get(CONF_PIN):
            dev = VizioAsync(
                DEVICE_ID,
                self._data[CONF_HOST],
                self._data[CONF_NAME],
                None,
                self._data[CONF_DEVICE_CLASS],
                session=async_get_clientsession(self.hass, False),
            )
            pair_data = await dev.pair(
                self._ch_type, self._pairing_token, user_input[CONF_PIN]
            )

            if pair_data:
                self._data[CONF_ACCESS_TOKEN] = pair_data.auth_token
                self._must_show_form = True

                unique_id = await VizioAsync.get_unique_id(
                    self._data[CONF_HOST],
                    self._data[CONF_ACCESS_TOKEN],
                    self._data[CONF_DEVICE_CLASS],
                    session=async_get_clientsession(self.hass, False),
                )

                # Set unique ID and abort if unique ID is already configured on an entry or a flow
                # with the unique ID is already in progress
                await self.async_set_unique_id(
                    unique_id=unique_id, raise_on_progress=True
                )
                self._abort_if_unique_id_configured()

                # pylint: disable=no-member # https://github.com/PyCQA/pylint/issues/3167
                if self.context["source"] == SOURCE_IMPORT:
                    # If user is pairing via config import, show different message
                    return await self.async_step_pairing_complete_import()

                return await self.async_step_tv_apps()

            # If no data was retrieved, it's assumed that the pairing attempt was not
            # successful
            errors[CONF_PIN] = "complete_pairing_failed"

        return self.async_show_form(
            step_id="pair_tv",
            data_schema=_get_pairing_schema(user_input),
            errors=errors,
        )
示例#10
0
def cli(ctx, ip: str, auth: str, device_type: str) -> None:
    logging.basicConfig(level=logging.INFO)

    ctx.obj = VizioAsync(DEFAULT_DEVICE_ID, ip, DEFAULT_DEVICE_NAME, auth, device_type)
示例#11
0
async def get_remote_keys_list(vizio: VizioAsync) -> None:
    table = tabulate(vizio.get_remote_keys_list(), headers=["App Name"])
    _LOGGER.info("\n%s", table)
示例#12
0
def get_volume_max(vizio: VizioAsync) -> None:
    _LOGGER.info("Max volume: %s", vizio.get_max_volume())
示例#13
0
    async def async_step_pair_tv(self,
                                 user_input: dict[str,
                                                  Any] = None) -> FlowResult:
        """
        Start pairing process for TV.

        Ask user for PIN to complete pairing process.
        """
        errors = {}

        # Start pairing process if it hasn't already started
        if not self._ch_type and not self._pairing_token:
            dev = VizioAsync(
                DEVICE_ID,
                self._data[CONF_HOST],
                self._data[CONF_NAME],
                None,
                self._data[CONF_DEVICE_CLASS],
                session=async_get_clientsession(self.hass, False),
            )
            pair_data = await dev.start_pair()

            if pair_data:
                self._ch_type = pair_data.ch_type
                self._pairing_token = pair_data.token
                return await self.async_step_pair_tv()

            return self.async_show_form(
                step_id="user",
                data_schema=_get_config_schema(self._data),
                errors={"base": "cannot_connect"},
            )

        # Complete pairing process if PIN has been provided
        if user_input and user_input.get(CONF_PIN):
            dev = VizioAsync(
                DEVICE_ID,
                self._data[CONF_HOST],
                self._data[CONF_NAME],
                None,
                self._data[CONF_DEVICE_CLASS],
                session=async_get_clientsession(self.hass, False),
            )
            pair_data = await dev.pair(self._ch_type, self._pairing_token,
                                       user_input[CONF_PIN])

            if pair_data:
                self._data[CONF_ACCESS_TOKEN] = pair_data.auth_token
                self._must_show_form = True

                if self.context["source"] == SOURCE_IMPORT:
                    # If user is pairing via config import, show different message
                    return await self.async_step_pairing_complete_import()

                return await self.async_step_pairing_complete()

            # If no data was retrieved, it's assumed that the pairing attempt was not
            # successful
            errors[CONF_PIN] = "complete_pairing_failed"

        return self.async_show_form(
            step_id="pair_tv",
            data_schema=_get_pairing_schema(user_input),
            errors=errors,
        )
示例#14
0
 cv.string,
 vol.Optional(CONF_ACCESS_TOKEN):
 cv.string,
 vol.Optional(CONF_NAME, default=DEFAULT_NAME):
 cv.string,
 vol.Optional(CONF_DEVICE_CLASS, default=DEFAULT_DEVICE_CLASS):
 vol.All(cv.string, vol.Lower,
         vol.In([DEVICE_CLASS_TV, DEVICE_CLASS_SPEAKER])),
 vol.Optional(CONF_VOLUME_STEP, default=DEFAULT_VOLUME_STEP):
 vol.All(vol.Coerce(int), vol.Range(min=1, max=10)),
 vol.Optional(CONF_APPS):
 vol.All(
     {
         vol.Exclusive(CONF_INCLUDE, "apps_filter"):
         vol.All(cv.ensure_list,
                 [vol.All(cv.string, vol.In(VizioAsync.get_apps_list()))]),
         vol.Exclusive(CONF_EXCLUDE, "apps_filter"):
         vol.All(cv.ensure_list,
                 [vol.All(cv.string, vol.In(VizioAsync.get_apps_list()))]),
         vol.Optional(CONF_ADDITIONAL_CONFIGS):
         vol.All(
             cv.ensure_list,
             [
                 {
                     vol.Required(CONF_NAME): cv.string,
                     vol.Required(CONF_CONFIG): {
                         vol.Required(CONF_APP_ID):
                         cv.string,
                         vol.Required(CONF_NAME_SPACE):
                         vol.Coerce(int),
                         vol.Optional(CONF_MESSAGE, default=None):