示例#1
0
def test_cfg_multiple_filters():
    a = validate_cfg({
        'test':
        True,
        'filter': {
            'thing_type': 'bla'
        },
        'channels': [{
            'filter': {
                'channel_uid': 'channel_filter'
            }
        }]
    })
    assert a is not None

    b = validate_cfg([{
        'test':
        True,
        'filter': [{
            'thing_type': 'bla'
        }],
        'channels': [{
            'filter': [{
                'channel_uid': 'channel_filter'
            }]
        }]
    }])
    assert b is not None

    # compare str because we have different instances of the filter class
    assert str(a) == str(b)
示例#2
0
def test_cfg_item_builder():
    c = validate_cfg({
        'test':
        True,
        'filter': {},
        'create items': [{
            'type': 'Switch',
            'name': '{thing_uid}'
        }],
        'channels': [{
            'filter': {},
            'link items': [{
                'type': 'Number',
                'name': '{thing_uid}'
            }],
        }]
    })

    a = list(c[0].get_items({'thing_uid': 'replaced_uid'}))
    assert a[0].type == 'Switch'
    assert a[0].name == 'replaced_uid'

    a = list(c[0].channels[0].get_items({'thing_uid': 'replaced_uid'}))
    assert a[0].type == 'Number'
    assert a[0].name == 'replaced_uid'
示例#3
0
def test_thing_cfg_types():
    assert validate_cfg({
        'test': True,
        'filter': {},
        'thing config': {
            1: 0,
            2: 'str',
            'Group1': ['asdf']
        },
    })
示例#4
0
def test_cfg_optional():
    assert validate_cfg({
        'test': True,
        'filter': {},
    })
示例#5
0
def test_cfg_err():
    assert None is validate_cfg({'test': True, 'filter1': {}}, 'filename')
    assert None is validate_cfg({'test': True, 'filter1': {}})
示例#6
0
    async def update_thing_config(self, path: Path, data=None):
        # we have to check the naming structure because we get file events for the whole folder
        _name = path.name.lower()
        if not _name.startswith('thing_') or not _name.endswith('.yml'):
            return None

        # only load if we don't supply the data
        if data is None:
            data = await async_get_things()

        # remove created items
        self.created_items.pop(path.name, None)
        created_items = self.created_items.setdefault(path.name, set())

        # shedule cleanup
        self.do_cleanup.reset()

        # output file
        output_file = path.with_suffix('.items')
        if output_file.is_file():
            output_file.unlink()

        # we also get events when the file gets deleted
        if not path.is_file():
            log.debug(f'File {path} does not exist -> skipping Thing configuration!')
            return None
        log.debug(f'Loading {path}!')

        # load the config file
        yml = HABApp.parameters.parameter_files._yml_setup
        with path.open(mode='r', encoding='utf-8') as file:
            try:
                cfg = yml.load(file)
            except Exception as e:
                HABAppError(log).add_exception(e).dump()
                return None

        # validate configuration
        cfg = validate_cfg(cfg, path.name)
        if cfg is None:
            return None

        # if one entry has test set we show an overview of all the things
        if any(map(lambda x: x.test, cfg)):
            log_overview(data, THING_ALIAS, 'Thing overview')

        # process each thing part in the cfg
        for cfg_entry in cfg:
            test: bool = cfg_entry.test
            things = list(apply_filters(cfg_entry.filter, data, test))

            # show a warning we found no Things
            if not things:
                log_warning(log, f'No things matched for {cfg_entry.filter}')
                continue

            # update thing configuration
            if cfg_entry.thing_config:
                await update_thing_cfg(cfg_entry.thing_config, things, test)

            try:
                # item creation for every thing
                create_items = {}
                shown_types = set()
                for thing in things:
                    thing_context = {k: thing.get(alias, '') for k, alias in THING_ALIAS.items()}

                    # create items without channel
                    for item_cfg in cfg_entry.get_items(thing_context):
                        name = item_cfg.name
                        if name in create_items:
                            raise ValueError(f'Duplicate item: {name}')
                        create_items[name] = item_cfg

                    # Channel overview, only if we have something configured
                    if test and cfg_entry.channels:
                        __thing_type = thing_context['thing_type']
                        if __thing_type not in shown_types:
                            shown_types.add(__thing_type)
                            log_overview(thing['channels'], CHANNEL_ALIAS, heading=f'Channels for {__thing_type}')

                    # do channel things
                    for channel_cfg in cfg_entry.channels:
                        channels = apply_filters(channel_cfg.filter, thing['channels'], test)
                        for channel in channels:
                            channel_context = {k: channel.get(alias, '') for k, alias in CHANNEL_ALIAS.items()}
                            channel_context.update(thing_context)

                            for item_cfg in channel_cfg.get_items(channel_context):
                                item_cfg.link = channel['uid']
                                name = item_cfg.name

                                if name in create_items:
                                    raise ValueError(f'Duplicate item: {name}')
                                create_items[name] = item_cfg

                    # newline only if we create logs
                    if test and (cfg_entry.create_items or cfg_entry.channels):
                        log.info('')
            except InvalidItemNameError as e:
                HABAppError(log).add_exception(e).dump()
                continue

            # Create all items
            for item_cfg in create_items.values():
                created = await create_item(item_cfg, test)
                if created:
                    created_items.add(item_cfg.name)

            self.do_cleanup.reset()

            create_items_file(output_file, create_items)