Example #1
0
def setup_scanner(hass, config, see, discovery_info=None):
    from custom_components.life360 import life360

    def auth_info_callback():
        _LOGGER.debug('Authenticating')
        return (_AUTHORIZATION_TOKEN, config[CONF_USERNAME],
                config[CONF_PASSWORD])

    interval = config.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)
    ok = False
    try:
        api = life360(auth_info_callback,
                      interval.total_seconds() - 1,
                      hass.config.path(config[CONF_FILENAME]))
        if api.get_circles():
            ok = True
    except Exception as exc:
        _LOGGER.error(exc_msg(exc))
    if not ok:
        _LOGGER.error('Life360 communication failed!')
        return False
    _LOGGER.debug('Life360 communication successful!')

    show_as_state = config[CONF_SHOW_AS_STATE]
    max_gps_accuracy = config.get(CONF_MAX_GPS_ACCURACY)
    max_update_wait = config.get(CONF_MAX_UPDATE_WAIT)
    prefix = config.get(CONF_PREFIX)
    members = config.get(CONF_MEMBERS)
    _LOGGER.debug('members = {}'.format(members))

    if members:
        _members = []
        for member in members:
            try:
                name = m_name(*member.split(','))
            except TypeError:
                name = ''
            if not name:
                _LOGGER.error(
                    'Ignoring invalid member name: "{}"'.format(member))
                continue
            _members.append(name)
        members = _members
        _LOGGER.debug('Processed members = {}'.format(members))
        if not members:
            _LOGGER.error('No listed member names were valid')
            return False

    Life360Scanner(hass, see, interval, show_as_state, max_gps_accuracy,
                   max_update_wait, prefix, members, api)
    return True
def setup_scanner(hass, config, see, discovery_info=None):
    from custom_components.life360 import life360

    def auth_info_callback():
        _LOGGER.debug('Authenticating')
        return (_AUTHORIZATION_TOKEN, config[CONF_USERNAME],
                config[CONF_PASSWORD])

    interval = config.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)
    ok = False
    try:
        api = life360(auth_info_callback,
                      interval.total_seconds() - 1,
                      hass.config.path(config[CONF_FILENAME]))
        if api.get_circles():
            ok = True
    except Exception as exc:
        exc_msg(exc)
    if not ok:
        _LOGGER.error('Life360 communication failed!')
        return False
    _LOGGER.debug('Life360 communication successful!')

    show_as_state = config[CONF_SHOW_AS_STATE]
    max_update_wait = config.get(CONF_MAX_UPDATE_WAIT)
    prefix = config.get(CONF_PREFIX)
    members = config.get(CONF_MEMBERS)
    _LOGGER.debug('members = {}'.format(members))

    if members:
        _members = []
        for member in members:
            try:
                f, l = member.lower().split(',')
            except (ValueError, AttributeError):
                _LOGGER.error('Invalid member name: {}'.format(member))
                return False
            _members.append((f.strip(), l.strip()))
        members = _members
        _LOGGER.debug('processed members = {}'.format(members))

    Life360Scanner(hass, see, interval, show_as_state, max_update_wait, prefix,
                   members, api)
    return True
Example #3
0
def setup_scanner(hass, config, see, discovery_info=None):
    from custom_components.life360 import life360

    def auth_info_callback():
        _LOGGER.debug('Authenticating')
        return (_AUTHORIZATION_TOKEN, config[CONF_USERNAME],
                config[CONF_PASSWORD])

    interval = config.get(CONF_SCAN_INTERVAL, DEFAULT_SCAN_INTERVAL)
    ok = False
    try:
        api = life360(auth_info_callback,
                      interval.total_seconds() - 1,
                      hass.config.path(config[CONF_FILENAME]))
        if api.get_circles():
            ok = True
    except Exception as exc:
        _LOGGER.error(exc_msg(exc))
    if not ok:
        _LOGGER.error('Life360 communication failed!')
        return False
    _LOGGER.debug('Life360 communication successful!')

    show_as_state = config[CONF_SHOW_AS_STATE]
    max_gps_accuracy = config.get(CONF_MAX_GPS_ACCURACY)
    max_update_wait = config.get(CONF_MAX_UPDATE_WAIT)
    prefix = config.get(CONF_PREFIX)
    members = config.get(CONF_MEMBERS)
    driving_speed = config.get(CONF_DRIVING_SPEED)
    _LOGGER.debug('Configured members = {}'.format(members))

    if members:
        _members = []
        for member in members:
            try:
                name = m_name(*member.split(','))
            except (TypeError, ValueError):
                _LOGGER.error(
                    'Ignoring invalid member name: "{}"'.format(member))
                continue
            _members.append(name)
        members = _members
        _LOGGER.debug('Processed members = {}'.format(members))
        if not members:
            _LOGGER.error('No listed member names were valid')
            return False

    Place = namedtuple('Place', ['name', 'latitude', 'longitude', 'radius'])

    def get_places():
        errs = 0
        while True:
            places = set()
            try:
                for circle in api.get_circles():
                    for place in api.get_circle_places(circle['id']):
                        name = place['name']
                        if name.lower() == HOME_ZONE:
                            continue
                        places.add(
                            Place(name, float(place['latitude']),
                                  float(place['longitude']),
                                  float(place['radius'])))
            except _API_EXCS + (KeyError, TypeError, ValueError) as exc:
                errs += 1
                if errs >= 3:
                    _LOGGER.error('get_places: {}'.format(exc_msg(exc)))
                    return None
            else:
                return places

    def zone_from_place(place):
        zone = Zone(hass, *place, None, DEFAULT_PASSIVE)
        zone.entity_id = generate_entity_id(ZN_ENTITY_ID_FORMAT, place.name,
                                            None, hass)
        zone.schedule_update_ha_state()
        return zone

    def log_places(msg, places):
        _LOGGER.debug('{} zones for Places: {}'.format(
            msg, '; '.join([
                '{}: {}, {}, {}'.format(*place)
                for place in sorted(places, key=lambda x: x.name.lower())
            ])))

    def zones_from_places(now=None):
        places = get_places()
        if places is None:
            return
        remove_places = set(zones.keys()) - places
        if remove_places:
            log_places('Removing', remove_places)
            for remove_place in remove_places:
                hass.add_job(zones.pop(remove_place).async_remove())
        add_places = places - set(zones.keys())
        if add_places:
            log_places('Adding', add_places)
            for add_place in add_places:
                zone = zone_from_place(add_place)
                zones[add_place] = zone

    add_zones = config.get(CONF_ADD_ZONES)
    zone_interval = config.get(CONF_ZONE_INTERVAL)
    if add_zones or zone_interval and add_zones != False:
        _LOGGER.debug('Checking Places')
        zones = {}
        zones_from_places()
        if zone_interval:
            _LOGGER.debug('Will check Places every: {}'.format(zone_interval))
            track_time_interval(hass, zones_from_places, zone_interval)

    Life360Scanner(hass, see, interval, show_as_state, max_gps_accuracy,
                   max_update_wait, prefix, members, driving_speed, api)
    return True