Example #1
0
async def _try_async_validate_config_item(hass,
                                          object_id,
                                          config,
                                          full_config=None):
    """Validate config item."""
    try:
        cv.slug(object_id)
        config = await async_validate_config_item(hass, config, full_config)
    except (vol.Invalid, HomeAssistantError) as ex:
        async_log_exception(ex, DOMAIN, full_config or config, hass)
        return None

    return config
    async def async_see(self, dev_id: str = None, state: str = None):
        """Create binary sensor.
        This method is a coroutine.
        """

        dev_id = cv.slug(str(dev_id).lower())
        device = self.devices.get(dev_id)
        """State received of already known device"""
        if device:
            await device.async_seen(state)
            await device.async_update_ha_state()
            return
        """State received of unknown device"""
        dev_id = util.ensure_unique_string(dev_id, self.devices.keys())
        device = JablotronSensor(self._hass, dev_id)
        self.devices[dev_id] = device

        await device.async_seen(state)
        """Update known_devices.yaml"""
        self._hass.async_create_task(
            self.async_update_config(self._hass.config.path(YAML_DEVICES),
                                     dev_id, device))

        self._async_add_entities([device])
        _LOGGER.debug('DeviceScanner.async_see(): added entity %s', device)
Example #3
0
def load_config(path: str, hass: HomeAssistantType, consider_home: timedelta):
    """Load devices from YAML configuration file."""
    dev_schema = vol.Schema({
        vol.Required('name'):
        cv.string,
        vol.Optional('track', default=False):
        cv.boolean,
        vol.Optional('mac', default=None):
        vol.Any(None, vol.All(cv.string, vol.Upper)),
        vol.Optional(CONF_AWAY_HIDE, default=DEFAULT_AWAY_HIDE):
        cv.boolean,
        vol.Optional('gravatar', default=None):
        vol.Any(None, cv.string),
        vol.Optional('picture', default=None):
        vol.Any(None, cv.string),
        vol.Optional(CONF_CONSIDER_HOME, default=consider_home):
        vol.All(cv.time_period, cv.positive_timedelta)
    })
    try:
        result = []
        devices = load_yaml_config_file(path)
        for dev_id, device in devices.items():
            try:
                device = dev_schema(device)
                device['dev_id'] = cv.slug(dev_id)
            except vol.Invalid as exp:
                log_exception(exp, dev_id, devices)
            else:
                result.append(Device(hass, **device))
        return result
    except (HomeAssistantError, FileNotFoundError):
        # When YAML file could not be loaded/did not contain a dict
        return []
Example #4
0
    def async_see(self,
                  mac: str = None,
                  dev_id: str = None,
                  host_name: str = None,
                  location_name: str = None,
                  gps: GPSType = None,
                  gps_accuracy=None,
                  battery: str = None,
                  attributes: dict = None):
        """Notify the device tracker that you see a device.

        This method is a coroutine.
        """
        if mac is None and dev_id is None:
            raise HomeAssistantError('Neither mac or device id passed in')
        elif mac is not None:
            mac = str(mac).upper()
            device = self.mac_to_dev.get(mac)
            if not device:
                dev_id = util.slugify(host_name or '') or util.slugify(mac)
        else:
            dev_id = cv.slug(str(dev_id).lower())
            device = self.devices.get(dev_id)

        if device:
            yield from device.async_seen(host_name, location_name, gps,
                                         gps_accuracy, battery, attributes)
            if device.track:
                yield from device.async_update_ha_state()
            return

        # If no device can be found, create it
        dev_id = util.ensure_unique_string(dev_id, self.devices.keys())
        device = Device(self.hass, self.consider_home, self.track_new, dev_id,
                        mac, (host_name or dev_id).replace('_', ' '))
        self.devices[dev_id] = device
        if mac is not None:
            self.mac_to_dev[mac] = device

        yield from device.async_seen(host_name, location_name, gps,
                                     gps_accuracy, battery, attributes)

        if device.track:
            yield from device.async_update_ha_state()

        self.hass.bus.async_fire(EVENT_NEW_DEVICE, {
            ATTR_ENTITY_ID: device.entity_id,
            ATTR_HOST_NAME: device.host_name,
        })

        # During init, we ignore the group
        if self.group is not None:
            yield from self.group.async_update_tracked_entity_ids(
                list(self.group.tracking) + [device.entity_id])

        # update known_devices.yaml
        self.hass.async_add_job(
            self.async_update_config(self.hass.config.path(YAML_DEVICES),
                                     dev_id, device))
Example #5
0
    def async_see(self, mac: str=None, dev_id: str=None, host_name: str=None,
                  location_name: str=None, gps: GPSType=None,
                  gps_accuracy=None, battery: str=None, attributes: dict=None):
        """Notify the device tracker that you see a device.

        This method is a coroutine.
        """
        if mac is None and dev_id is None:
            raise HomeAssistantError('Neither mac or device id passed in')
        elif mac is not None:
            mac = str(mac).upper()
            device = self.mac_to_dev.get(mac)
            if not device:
                dev_id = util.slugify(host_name or '') or util.slugify(mac)
        else:
            dev_id = cv.slug(str(dev_id).lower())
            device = self.devices.get(dev_id)

        if device:
            yield from device.async_seen(host_name, location_name, gps,
                                         gps_accuracy, battery, attributes)
            if device.track:
                yield from device.async_update_ha_state()
            return

        # If no device can be found, create it
        dev_id = util.ensure_unique_string(dev_id, self.devices.keys())
        device = Device(
            self.hass, self.consider_home, self.track_new,
            dev_id, mac, (host_name or dev_id).replace('_', ' '))
        self.devices[dev_id] = device
        if mac is not None:
            self.mac_to_dev[mac] = device

        yield from device.async_seen(host_name, location_name, gps,
                                     gps_accuracy, battery, attributes)

        if device.track:
            yield from device.async_update_ha_state()

        self.hass.bus.async_fire(EVENT_NEW_DEVICE, {
            ATTR_ENTITY_ID: device.entity_id,
            ATTR_HOST_NAME: device.host_name,
        })

        # During init, we ignore the group
        if self.group is not None:
            yield from self.group.async_update_tracked_entity_ids(
                list(self.group.tracking) + [device.entity_id])

        # lookup mac vendor string to be stored in config
        yield from device.set_vendor_for_mac()

        # update known_devices.yaml
        self.hass.async_add_job(
            self.async_update_config(self.hass.config.path(YAML_DEVICES),
                                     dev_id, device)
        )
Example #6
0
async def _try_async_validate_config_item(hass, object_id, config, full_config=None):
    """Validate config item."""
    raw_config = None
    with suppress(ValueError):  # Invalid config
        raw_config = dict(config)

    try:
        cv.slug(object_id)
        config = await async_validate_config_item(hass, config, full_config)
    except (vol.Invalid, HomeAssistantError) as ex:
        async_log_exception(ex, DOMAIN, full_config or config, hass)
        return None

    if isinstance(config, BlueprintInputs):
        return config

    config = ScriptConfig(config)
    config.raw_config = raw_config
    return config
Example #7
0
async def _try_async_validate_config_item(hass,
                                          object_id,
                                          config,
                                          full_config=None):
    """Validate config item."""
    raw_config = None
    try:
        raw_config = dict(config)
    except ValueError:
        # Invalid config
        pass

    try:
        cv.slug(object_id)
        config = await async_validate_config_item(hass, config, full_config)
    except (vol.Invalid, HomeAssistantError) as ex:
        async_log_exception(ex, DOMAIN, full_config or config, hass)
        return None

    config = ScriptConfig(config)
    config.raw_config = raw_config
    return config
Example #8
0
    def see(self,
            mac: str = None,
            dev_id: str = None,
            host_name: str = None,
            location_name: str = None,
            gps: GPSType = None,
            gps_accuracy=None,
            battery: str = None,
            attributes: dict = None):
        """Notify the device tracker that you see a device."""
        with self.lock:
            if mac is None and dev_id is None:
                raise HomeAssistantError('Neither mac or device id passed in')
            elif mac is not None:
                mac = str(mac).upper()
                device = self.mac_to_dev.get(mac)
                if not device:
                    dev_id = util.slugify(host_name or '') or util.slugify(mac)
            else:
                dev_id = cv.slug(str(dev_id).lower())
                device = self.devices.get(dev_id)

            if device:
                device.seen(host_name, location_name, gps, gps_accuracy,
                            battery, attributes)
                if device.track:
                    device.update_ha_state()
                return

            # If no device can be found, create it
            dev_id = util.ensure_unique_string(dev_id, self.devices.keys())
            device = Device(self.hass, self.consider_home, self.track_new,
                            dev_id, mac, (host_name
                                          or dev_id).replace('_', ' '))
            self.devices[dev_id] = device
            if mac is not None:
                self.mac_to_dev[mac] = device

            device.seen(host_name, location_name, gps, gps_accuracy, battery,
                        attributes)
            if device.track:
                device.update_ha_state()

            # During init, we ignore the group
            if self.group is not None:
                self.group.update_tracked_entity_ids(
                    list(self.group.tracking) + [device.entity_id])
            update_config(self.hass.config.path(YAML_DEVICES), dev_id, device)
Example #9
0
    def see(self, mac=None, dev_id=None, host_name=None, location_name=None, gps=None, gps_accuracy=None, battery=None):
        """Notify the device tracker that you see a device."""
        with self.lock:
            if mac is None and dev_id is None:
                raise HomeAssistantError("Neither mac or device id passed in")
            elif mac is not None:
                mac = mac.upper()
                device = self.mac_to_dev.get(mac)
                if not device:
                    dev_id = util.slugify(host_name or "") or util.slugify(mac)
            else:
                dev_id = cv.slug(str(dev_id).lower())
                device = self.devices.get(dev_id)

            if device:
                device.seen(host_name, location_name, gps, gps_accuracy, battery)
                if device.track:
                    device.update_ha_state()
                return

            # If no device can be found, create it
            dev_id = util.ensure_unique_string(dev_id, self.devices.keys())
            device = Device(
                self.hass,
                self.consider_home,
                self.home_range,
                self.track_new,
                dev_id,
                mac,
                (host_name or dev_id).replace("_", " "),
            )
            self.devices[dev_id] = device
            if mac is not None:
                self.mac_to_dev[mac] = device

            device.seen(host_name, location_name, gps, gps_accuracy, battery)
            if device.track:
                device.update_ha_state()

            # During init, we ignore the group
            if self.group is not None:
                self.group.update_tracked_entity_ids(list(self.group.tracking) + [device.entity_id])
            update_config(self.hass.config.path(YAML_DEVICES), dev_id, device)
Example #10
0
        icon: str | None = None,
        consider_home: timedelta | None = None,
    ) -> None:
        """Notify the device tracker that you see a device.

        This method is a coroutine.
        """
        registry = er.async_get(self.hass)
        if mac is None and dev_id is None:
            raise HomeAssistantError("Neither mac or device id passed in")
        if mac is not None:
            mac = str(mac).upper()
            if (device := self.mac_to_dev.get(mac)) is None:
                dev_id = util.slugify(host_name or "") or util.slugify(mac)
        else:
            dev_id = cv.slug(str(dev_id).lower())
            device = self.devices.get(dev_id)

        if device is not None:
            await device.async_seen(
                host_name,
                location_name,
                gps,
                gps_accuracy,
                battery,
                attributes,
                source_type,
                consider_home,
            )
            if device.track:
                device.async_write_ha_state()
Example #11
0
    async def async_see(
            self, mac: str = None, dev_id: str = None, host_name: str = None,
            location_name: str = None, gps: GPSType = None,
            gps_accuracy: int = None, battery: int = None,
            attributes: dict = None, source_type: str = SOURCE_TYPE_GPS,
            picture: str = None, icon: str = None,
            consider_home: timedelta = None):
        """Notify the device tracker that you see a device.

        This method is a coroutine.
        """
        if mac is None and dev_id is None:
            raise HomeAssistantError('Neither mac or device id passed in')
        if mac is not None:
            mac = str(mac).upper()
            device = self.mac_to_dev.get(mac)
            if not device:
                dev_id = util.slugify(host_name or '') or util.slugify(mac)
        else:
            dev_id = cv.slug(str(dev_id).lower())
            device = self.devices.get(dev_id)

        if device:
            await device.async_seen(
                host_name, location_name, gps, gps_accuracy, battery,
                attributes, source_type, consider_home)
            if device.track:
                await device.async_update_ha_state()
            return

        # If no device can be found, create it
        dev_id = util.ensure_unique_string(dev_id, self.devices.keys())
        device = Device(
            self.hass, consider_home or self.consider_home, self.track_new,
            dev_id, mac, (host_name or dev_id).replace('_', ' '),
            picture=picture, icon=icon,
            hide_if_away=self.defaults.get(CONF_AWAY_HIDE, DEFAULT_AWAY_HIDE))
        self.devices[dev_id] = device
        if mac is not None:
            self.mac_to_dev[mac] = device

        await device.async_seen(
            host_name, location_name, gps, gps_accuracy, battery, attributes,
            source_type)

        if device.track:
            await device.async_update_ha_state()

        # During init, we ignore the group
        if self.group and self.track_new:
            self.hass.async_create_task(
                self.hass.async_call(
                    DOMAIN_GROUP, SERVICE_SET, {
                        ATTR_OBJECT_ID: util.slugify(GROUP_NAME_ALL_DEVICES),
                        ATTR_VISIBLE: False,
                        ATTR_NAME: GROUP_NAME_ALL_DEVICES,
                        ATTR_ADD_ENTITIES: [device.entity_id]}))

        self.hass.bus.async_fire(EVENT_NEW_DEVICE, {
            ATTR_ENTITY_ID: device.entity_id,
            ATTR_HOST_NAME: device.host_name,
            ATTR_MAC: device.mac,
        })

        # update known_devices.yaml
        self.hass.async_create_task(
            self.async_update_config(
                self.hass.config.path(YAML_DEVICES), dev_id, device)
        )
Example #12
0
    async def async_see(
        self,
        mac: str = None,
        dev_id: str = None,
        host_name: str = None,
        location_name: str = None,
        gps: GPSType = None,
        gps_accuracy: int = None,
        battery: int = None,
        attributes: dict = None,
        source_type: str = SOURCE_TYPE_GPS,
        picture: str = None,
        icon: str = None,
        consider_home: timedelta = None,
    ):
        """Notify the device tracker that you see a device.

        This method is a coroutine.
        """
        registry = await async_get_registry(self.hass)
        if mac is None and dev_id is None:
            raise HomeAssistantError("Neither mac or device id passed in")
        if mac is not None:
            mac = str(mac).upper()
            device = self.mac_to_dev.get(mac)
            if not device:
                dev_id = util.slugify(host_name or "") or util.slugify(mac)
        else:
            dev_id = cv.slug(str(dev_id).lower())
            device = self.devices.get(dev_id)

        if device:
            await device.async_seen(
                host_name,
                location_name,
                gps,
                gps_accuracy,
                battery,
                attributes,
                source_type,
                consider_home,
            )
            if device.track:
                await device.async_update_ha_state()
            return

        # Guard from calling see on entity registry entities.
        entity_id = f"{DOMAIN}.{dev_id}"
        if registry.async_is_registered(entity_id):
            LOGGER.error("The see service is not supported for this entity %s",
                         entity_id)
            return

        # If no device can be found, create it
        dev_id = util.ensure_unique_string(dev_id, self.devices.keys())
        device = Device(
            self.hass,
            consider_home or self.consider_home,
            self.track_new,
            dev_id,
            mac,
            picture=picture,
            icon=icon,
        )
        self.devices[dev_id] = device
        if mac is not None:
            self.mac_to_dev[mac] = device

        await device.async_seen(
            host_name,
            location_name,
            gps,
            gps_accuracy,
            battery,
            attributes,
            source_type,
        )

        if device.track:
            await device.async_update_ha_state()

        self.hass.bus.async_fire(
            EVENT_NEW_DEVICE,
            {
                ATTR_ENTITY_ID: device.entity_id,
                ATTR_HOST_NAME: device.host_name,
                ATTR_MAC: device.mac,
            },
        )

        # update known_devices.yaml
        self.hass.async_create_task(
            self.async_update_config(self.hass.config.path(YAML_DEVICES),
                                     dev_id, device))
Example #13
0
    async def async_see(self,
                        mac: str = None,
                        dev_id: str = None,
                        host_name: str = None,
                        location_name: str = None,
                        gps: GPSType = None,
                        gps_accuracy: int = None,
                        battery: int = None,
                        attributes: dict = None,
                        source_type: str = SOURCE_TYPE_GPS,
                        picture: str = None,
                        icon: str = None,
                        consider_home: timedelta = None):
        """Notify the device tracker that you see a device.

        This method is a coroutine.
        """
        if mac is None and dev_id is None:
            raise HomeAssistantError('Neither mac or device id passed in')
        elif mac is not None:
            mac = str(mac).upper()
            device = self.mac_to_dev.get(mac)
            if not device:
                dev_id = util.slugify(host_name or '') or util.slugify(mac)
        else:
            dev_id = cv.slug(str(dev_id).lower())
            device = self.devices.get(dev_id)

        if device:
            await device.async_seen(host_name, location_name, gps,
                                    gps_accuracy, battery, attributes,
                                    source_type, consider_home)
            if device.track:
                await device.async_update_ha_state()
            return

        # If no device can be found, create it
        dev_id = util.ensure_unique_string(dev_id, self.devices.keys())
        device = Device(self.hass,
                        consider_home or self.consider_home,
                        self.track_new,
                        dev_id,
                        mac, (host_name or dev_id).replace('_', ' '),
                        picture=picture,
                        icon=icon,
                        hide_if_away=self.defaults.get(CONF_AWAY_HIDE,
                                                       DEFAULT_AWAY_HIDE))
        self.devices[dev_id] = device
        if mac is not None:
            self.mac_to_dev[mac] = device

        await device.async_seen(host_name, location_name, gps, gps_accuracy,
                                battery, attributes, source_type)

        if device.track:
            await device.async_update_ha_state()

        # During init, we ignore the group
        if self.group and self.track_new:
            self.hass.async_create_task(
                self.hass.async_call(
                    DOMAIN_GROUP, SERVICE_SET, {
                        ATTR_OBJECT_ID: util.slugify(GROUP_NAME_ALL_DEVICES),
                        ATTR_VISIBLE: False,
                        ATTR_NAME: GROUP_NAME_ALL_DEVICES,
                        ATTR_ADD_ENTITIES: [device.entity_id]
                    }))

        self.hass.bus.async_fire(
            EVENT_NEW_DEVICE, {
                ATTR_ENTITY_ID: device.entity_id,
                ATTR_HOST_NAME: device.host_name,
                ATTR_MAC: device.mac,
            })

        # update known_devices.yaml
        self.hass.async_create_task(
            self.async_update_config(self.hass.config.path(YAML_DEVICES),
                                     dev_id, device))
Example #14
0
    def async_see(self, mac: str=None, dev_id: str=None, host_name: str=None,
                  location_name: str=None, gps: GPSType=None,
                  gps_accuracy=None, battery: str=None, attributes: dict=None,
                  source_type: str=SOURCE_TYPE_GPS, picture: str=None,
                  icon: str=None):
        """Notify the device tracker that you see a device.

        This method is a coroutine.
        """
        if mac is None and dev_id is None:
            raise HomeAssistantError('Neither mac or device id passed in')
        elif mac is not None:
            mac = str(mac).upper()
            device = self.mac_to_dev.get(mac)
            if not device:
                dev_id = util.slugify(host_name or '') or util.slugify(mac)
        else:
            dev_id = cv.slug(str(dev_id).lower())
            device = self.devices.get(dev_id)

        if device:
            yield from device.async_seen(
                host_name, location_name, gps, gps_accuracy, battery,
                attributes, source_type)
            if device.track:
                yield from device.async_update_ha_state()
            return

        # If no device can be found, create it
        dev_id = util.ensure_unique_string(dev_id, self.devices.keys())
        device = Device(
            self.hass, self.consider_home, self.track_new,
            dev_id, mac, (host_name or dev_id).replace('_', ' '),
            picture=picture, icon=icon,
            hide_if_away=self.defaults.get(CONF_AWAY_HIDE, DEFAULT_AWAY_HIDE))
        self.devices[dev_id] = device
        if mac is not None:
            self.mac_to_dev[mac] = device

        yield from device.async_seen(
            host_name, location_name, gps, gps_accuracy, battery, attributes,
            source_type)

        if device.track:
            yield from device.async_update_ha_state()

        # During init, we ignore the group
        if self.group and self.track_new:
            self.group.async_set_group(
                self.hass, util.slugify(GROUP_NAME_ALL_DEVICES), visible=False,
                name=GROUP_NAME_ALL_DEVICES, add=[device.entity_id])

        # lookup mac vendor string to be stored in config
        yield from device.set_vendor_for_mac()

        self.hass.bus.async_fire(EVENT_NEW_DEVICE, {
            ATTR_ENTITY_ID: device.entity_id,
            ATTR_HOST_NAME: device.host_name,
            ATTR_MAC: device.mac,
            ATTR_VENDOR: device.vendor,
        })

        # update known_devices.yaml
        self.hass.async_add_job(
            self.async_update_config(
                self.hass.config.path(YAML_DEVICES), dev_id, device)
        )
Example #15
0
    def async_see(self, mac: str = None, dev_id: str = None,
                  host_name: str = None, location_name: str = None,
                  gps: GPSType = None, gps_accuracy=None, battery: str = None,
                  attributes: dict = None, source_type: str = SOURCE_TYPE_GPS,
                  picture: str = None, icon: str = None):
        """Notify the device tracker that you see a device.

        This method is a coroutine.
        """
        if mac is None and dev_id is None:
            raise HomeAssistantError('Neither mac or device id passed in')
        elif mac is not None:
            mac = str(mac).upper()
            device = self.mac_to_dev.get(mac)
            if not device:
                dev_id = util.slugify(host_name or '') or util.slugify(mac)
        else:
            dev_id = cv.slug(str(dev_id).lower())
            device = self.devices.get(dev_id)

        if device:
            yield from device.async_seen(
                host_name, location_name, gps, gps_accuracy, battery,
                attributes, source_type)
            if device.track:
                yield from device.async_update_ha_state()
            return

        # If no device can be found, create it
        dev_id = util.ensure_unique_string(dev_id, self.devices.keys())
        device = Device(
            self.hass, self.consider_home, self.track_new,
            dev_id, mac, (host_name or dev_id).replace('_', ' '),
            picture=picture, icon=icon,
            hide_if_away=self.defaults.get(CONF_AWAY_HIDE, DEFAULT_AWAY_HIDE))
        self.devices[dev_id] = device
        if mac is not None:
            self.mac_to_dev[mac] = device

        yield from device.async_seen(
            host_name, location_name, gps, gps_accuracy, battery, attributes,
            source_type)

        if device.track:
            yield from device.async_update_ha_state()

        # During init, we ignore the group
        if self.group and self.track_new:
            self.group.async_set_group(
                self.hass, util.slugify(GROUP_NAME_ALL_DEVICES), visible=False,
                name=GROUP_NAME_ALL_DEVICES, add=[device.entity_id])

        # lookup mac vendor string to be stored in config
        yield from device.set_vendor_for_mac()

        self.hass.bus.async_fire(EVENT_NEW_DEVICE, {
            ATTR_ENTITY_ID: device.entity_id,
            ATTR_HOST_NAME: device.host_name,
            ATTR_MAC: device.mac,
            ATTR_VENDOR: device.vendor,
        })

        # update known_devices.yaml
        self.hass.async_add_job(
            self.async_update_config(
                self.hass.config.path(YAML_DEVICES), dev_id, device)
        )