Exemple #1
0
    async def found_device(self, upnp_device):
        if self.device:
            self.logger.error("Device exists already, do not create a new one")
            return

        self.upnp_device = upnp_device
        # build upnp/aiohttp requester
        session = aiohttp.ClientSession()
        requester = AiohttpSessionRequester(session, True)
        # ensure event handler has been started
        server_host = await async_get_local_ip()
        if server_host:
            server_host = server_host[1]
        else:
            self.logger.error(f"Failed to add device {self.device}")
        server_port = DEFAULT_LISTEN_PORT
        event_handler = await self.async_start_event_handler(
            server_host, server_port, requester
        )

        # wrap with DmrDevice
        dlna_device = DmrDevice(self.upnp_device, event_handler)

        # create our own device
        self.device = DlnaDmrDevice(self, dlna_device)
        self.logger.debug("Adding device: %s", self.device)

        await self.updateDeviceReadings()
        await fhem.readingsSingleUpdate(self.hash, "state", "online", 1)
        self.update_task = self.create_async_task(self.update())
Exemple #2
0
    async def test_action_not_exists(self):
        r = UpnpTestRequester(RESPONSE_MAP)
        factory = UpnpFactory(r)
        device = await factory.async_create_device('http://localhost:1234/dmr')
        event_handler = UpnpEventHandler('http://localhost:11302', r)
        profile = DmrDevice(device, event_handler=event_handler)

        # doesn't error
        assert profile._action('RC', 'NonExisting') is None
Exemple #3
0
    async def test_action_not_exists(self):
        """Test getting non-existing action."""
        r = UpnpTestRequester(RESPONSE_MAP)
        factory = UpnpFactory(r)
        device = await factory.async_create_device("http://localhost:1234/dmr")
        event_handler = UpnpEventHandler("http://localhost:11302", r)
        profile = DmrDevice(device, event_handler=event_handler)

        # doesn't error
        assert profile._action("RC", "NonExisting") is None
Exemple #4
0
async def async_setup_platform(hass: HomeAssistantType,
                               config,
                               async_add_entities,
                               discovery_info=None):
    """Set up DLNA DMR platform."""
    if config.get(CONF_URL) is not None:
        url = config[CONF_URL]
        name = config.get(CONF_NAME)
    elif discovery_info is not None:
        url = discovery_info["ssdp_description"]
        name = discovery_info.get("name")

    if DLNA_DMR_DATA not in hass.data:
        hass.data[DLNA_DMR_DATA] = {}

    if "lock" not in hass.data[DLNA_DMR_DATA]:
        hass.data[DLNA_DMR_DATA]["lock"] = asyncio.Lock()

    # build upnp/aiohttp requester
    from async_upnp_client.aiohttp import AiohttpSessionRequester

    session = async_get_clientsession(hass)
    requester = AiohttpSessionRequester(session, True)

    # ensure event handler has been started
    with await hass.data[DLNA_DMR_DATA]["lock"]:
        server_host = config.get(CONF_LISTEN_IP)
        if server_host is None:
            server_host = get_local_ip()
        server_port = config.get(CONF_LISTEN_PORT, DEFAULT_LISTEN_PORT)
        callback_url_override = config.get(CONF_CALLBACK_URL_OVERRIDE)
        event_handler = await async_start_event_handler(
            hass, server_host, server_port, requester, callback_url_override)

    # create upnp device
    from async_upnp_client import UpnpFactory

    factory = UpnpFactory(requester, disable_state_variable_validation=True)
    try:
        upnp_device = await factory.async_create_device(url)
    except (asyncio.TimeoutError, aiohttp.ClientError):
        raise PlatformNotReady()

    # wrap with DmrDevice
    from async_upnp_client.profiles.dlna import DmrDevice

    dlna_device = DmrDevice(upnp_device, event_handler)

    # create our own device
    device = DlnaDmrDevice(dlna_device, name)
    _LOGGER.debug("Adding device: %s", device)
    async_add_entities([device], True)
Exemple #5
0
    async def _device_connect(self, location: str) -> None:
        """Connect to the device now that it's available."""
        _LOGGER.debug("Connecting to device at %s", location)

        async with self._device_lock:
            if self._device:
                _LOGGER.debug("Trying to connect when device already connected")
                return

            domain_data = get_domain_data(self.hass)

            # Connect to the base UPNP device
            upnp_device = await domain_data.upnp_factory.async_create_device(location)

            # Create/get event handler that is reachable by the device, using
            # the connection's local IP to listen only on the relevant interface
            _, event_ip = await async_get_local_ip(location, self.hass.loop)
            self._event_addr = self._event_addr._replace(host=event_ip)
            event_handler = await domain_data.async_get_event_notifier(
                self._event_addr, self.hass
            )

            # Create profile wrapper
            self._device = DmrDevice(upnp_device, event_handler)

            self.location = location

            # Subscribe to event notifications
            try:
                self._device.on_event = self._on_event
                await self._device.async_subscribe_services(auto_resubscribe=True)
            except UpnpError as err:
                # Don't leave the device half-constructed
                self._device.on_event = None
                self._device = None
                await domain_data.async_release_event_notifier(self._event_addr)
                _LOGGER.debug("Error while subscribing during device connect: %r", err)
                raise

        if (
            not self.registry_entry
            or not self.registry_entry.config_entry_id
            or self.registry_entry.device_id
        ):
            return

        # Create linked HA DeviceEntry now the information is known.
        dev_reg = device_registry.async_get(self.hass)
        device_entry = dev_reg.async_get_or_create(
            config_entry_id=self.registry_entry.config_entry_id,
            # Connections are based on the root device's UDN, and the DMR
            # embedded device's UDN. They may be the same, if the DMR is the
            # root device.
            connections={
                (
                    device_registry.CONNECTION_UPNP,
                    self._device.profile_device.root_device.udn,
                ),
                (device_registry.CONNECTION_UPNP, self._device.udn),
            },
            identifiers={(DOMAIN, self.unique_id)},
            default_manufacturer=self._device.manufacturer,
            default_model=self._device.model_name,
            default_name=self._device.name,
        )

        # Update entity registry to link to the device
        ent_reg = entity_registry.async_get(self.hass)
        ent_reg.async_get_or_create(
            self.registry_entry.domain,
            self.registry_entry.platform,
            self.unique_id,
            device_id=device_entry.id,
        )