Example #1
0
def _env_var_yaml(loader, node):
    """Load environment variables and embed it into the configuration YAML."""
    if node.value in os.environ:
        return os.environ[node.value]
    else:
        _LOGGER.error("Environment variable %s not defined.", node.value)
        raise BluMateError(node.value)
Example #2
0
def load_yaml(fname):
    """Load a YAML file."""
    try:
        with open(fname, encoding='utf-8') as conf_file:
            # If configuration file is empty YAML returns None
            # We convert that to an empty dict
            return yaml.load(conf_file, Loader=SafeLineLoader) or {}
    except yaml.YAMLError as exc:
        _LOGGER.error(exc)
        raise BluMateError(exc)
Example #3
0
def load_yaml_config_file(config_path):
    """Parse a YAML configuration file."""
    conf_dict = load_yaml(config_path)

    if not isinstance(conf_dict, dict):
        _LOGGER.error(
            'The configuration file %s does not contain a dictionary',
            os.path.basename(config_path))
        raise BluMateError()

    return conf_dict
Example #4
0
def from_config(config, config_validation=True):
    """Turn a condition configuration into a method."""
    factory = getattr(sys.modules[__name__],
                      FROM_CONFIG_FORMAT.format(config.get(CONF_CONDITION)),
                      None)

    if factory is None:
        raise BluMateError('Invalid condition "{}" specified {}'.format(
            config.get(CONF_CONDITION), config))

    return factory(config, config_validation)
Example #5
0
    def __call__(self, method, path, data=None):
        """Make a call to the Home Assistant API."""
        if data is not None:
            data = json.dumps(data, cls=JSONEncoder)

        url = urllib.parse.urljoin(self.base_url, path)

        try:
            if method == METHOD_GET:
                return requests.get(
                    url, params=data, timeout=5, headers=self._headers)
            else:
                return requests.request(
                    method, url, data=data, timeout=5, headers=self._headers)

        except requests.exceptions.ConnectionError:
            _LOGGER.exception("Error connecting to server")
            raise BluMateError("Error connecting to server")

        except requests.exceptions.Timeout:
            error = "Timeout when talking to {}".format(self.host)
            _LOGGER.exception(error)
            raise BluMateError(error)
Example #6
0
    def start(self):
        """Start the instance."""
        # Ensure a local API exists to connect with remote
        if 'api' not in self.config.components:
            if not bootstrap.setup_component(self, 'api'):
                raise BluMateError(
                    'Unable to setup local API to receive events')

        bm.create_timer(self)

        self.bus.fire(bm.EVENT_BLUMATE_START,
                      origin=bm.EventOrigin.remote)

        # Give eventlet time to startup
        import eventlet
        eventlet.sleep(0.1)

        # Setup that events from remote_api get forwarded to local_api
        # Do this after we fire START, otherwise HTTP is not started
        if not connect_remote_events(self.remote_api, self.config.api):
            raise BluMateError((
                'Could not setup event forwarding from api {} to '
                'local api {}').format(self.remote_api, self.config.api))
Example #7
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 BluMateError('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 #8
0
    def __init__(self, remote_api, local_api=None):
        """Initalize the forward instance."""
        if not remote_api.validate_api():
            raise BluMateError(
                "Remote API at {}:{} not valid: {}".format(
                    remote_api.host, remote_api.port, remote_api.status))

        self.remote_api = remote_api

        self.pool = pool = bm.create_worker_pool()

        self.bus = EventBus(remote_api, pool)
        self.services = bm.ServiceRegistry(self.bus, pool)
        self.states = StateMachine(self.bus, self.remote_api)
        self.config = bm.Config()

        self.config.api = local_api
Example #9
0
    def fire(self, event_type, event_data=None, origin=EventOrigin.local):
        """Fire an event."""
        if not self._pool.running:
            raise BluMateError('BluMate has shut down.')

        with self._lock:
            # Copy the list of the current listeners because some listeners
            # remove themselves as a listener while being executed which
            # causes the iterator to be confused.
            get = self._listeners.get
            listeners = get(MATCH_ALL, []) + get(event_type, [])

            event = Event(event_type, event_data, origin)

            if event_type != EVENT_TIME_CHANGED:
                _LOGGER.info("Bus:Handling %s", event)

            if not listeners:
                return

            job_priority = JobPriority.from_event_type(event_type)

            for func in listeners:
                self._pool.add_job(job_priority, (func, event))
Example #10
0
def _raise_on_error(result):
    """Raise error if error result."""
    if result != 0:
        raise BluMateError('Error talking to MQTT: {}'.format(result))