def get_create_item(cls,
                        name: str,
                        write_topic: Optional[str] = None,
                        initial_value=None) -> 'MqttPairItem':
        """Creates a new item in HABApp and returns it or returns the already existing one with the given name.
        HABApp tries to automatically derive the write topic from the item name. In cases where this does not
        work it can be specified manually.

        :param name: item name (topic that reports the state)
        :param write_topic: topic that is used to write values or ``None`` (default) to build it automatically
        :param initial_value: state the item will have if it gets created
        :return: item
        """
        assert isinstance(name, str), type(name)

        # try to build write topic
        if write_topic is None:
            write_topic = build_write_topic(name)

        try:
            item = Items.get_item(name)
        except Items.ItemNotFoundException:
            item = cls(name,
                       write_topic=write_topic,
                       initial_value=initial_value)
            Items.add_item(item)

        assert isinstance(item, cls), f'{cls} != {type(item)}'
        return item
def add_to_registry(item: 'HABApp.openhab.items.OpenhabItem', set_value=False):
    name = item.name
    for grp in item.groups:
        MEMBERS.setdefault(grp, set()).add(name)

    if not Items.item_exists(name):
        return Items.add_item(item)

    existing = Items.get_item(name)
    if isinstance(existing, item.__class__):
        # If we load directly through the API and not through an event we have to set the value
        if set_value:
            existing.set_value(item.value)

        # remove old groups
        for grp in set(existing.groups) - set(item.groups):
            MEMBERS.get(grp, set()).discard(name)

        # same type - it was only an item update (e.g. label)!
        existing.tags = item.tags
        existing.groups = item.groups
        return None

    log_warning(
        log,
        f'Item type changed from {existing.__class__} to {item.__class__}')

    # Replace existing item with the updated definition
    Items.pop_item(name)
    Items.add_item(item)
    async def on_connect_function(self):
        data = await async_get_items(disconnect_on_error=True,
                                     all_metadata=True)
        if data is None:
            return None

        fresh_item_sync()

        found_items = len(data)
        for _dict in data:
            item_name = _dict['name']
            new_item = map_item(
                item_name, _dict['type'], _dict['state'],
                frozenset(_dict['tags']), frozenset(_dict['groupNames']),
                _dict.get('metadata',
                          {}))  # type: HABApp.openhab.items.OpenhabItem
            if new_item is None:
                continue
            add_to_registry(new_item, True)

        # remove items which are no longer available
        ist = set(Items.get_all_item_names())
        soll = {k['name'] for k in data}
        for k in ist - soll:
            if isinstance(Items.get_item(k), HABApp.openhab.items.OpenhabItem):
                Items.pop_item(k)

        log.info(f'Updated {found_items:d} Items')

        # try to update things, too
        data = await async_get_things(disconnect_on_error=True)
        if data is None:
            return None

        Thing = HABApp.openhab.items.Thing
        for t_dict in data:
            name = t_dict['UID']
            try:
                thing = Items.get_item(name)
                if not isinstance(thing, Thing):
                    log.warning(
                        f'Item {name} has the wrong type ({type(thing)}), expected Thing'
                    )
                    thing = Thing(name)
            except Items.ItemNotFoundException:
                thing = Thing(name)

            thing.status = t_dict['statusInfo']['status']
            Items.add_item(thing)

        # remove things which were deleted
        ist = set(Items.get_all_item_names())
        soll = {k['UID'] for k in data}
        for k in ist - soll:
            if isinstance(Items.get_item(k), Thing):
                Items.pop_item(k)

        log.info(f'Updated {len(data):d} Things')
        return None
def test_pop(clean_reg):
    Items.add_item(Item('test'))
    assert Items.item_exists('test')

    with pytest.raises(Items.ItemNotFoundException):
        Items.pop_item('asdfadsf')

    Items.pop_item('test')
    assert not Items.item_exists('test')
def test_search_name():
    item1 = BaseValueItem('item_1a')
    item2 = Item('item_2a')

    assert Rule.get_items() == []

    Items.add_item(item1)
    Items.add_item(item2)

    assert Rule.get_items() == [item1, item2]
    assert Rule.get_items(name=r'\da') == [item1, item2]
    def test_item(self):

        NAME = 'test'
        created_item = Item(NAME)
        Items.add_item(created_item)

        self.assertTrue(Items.item_exists(NAME))
        self.assertIs(created_item, Items.get_item(NAME))

        self.assertEqual(Items.get_all_item_names(), [NAME])
        self.assertEqual(Items.get_all_items(), [created_item])

        self.assertIs(created_item, Items.pop_item(NAME))
        self.assertEqual(Items.get_all_items(), [])
def test_search_type():
    item1 = BaseValueItem('item_1')
    item2 = Item('item_2')

    assert Rule.get_items() == []

    Items.add_item(item1)
    Items.add_item(item2)

    assert Rule.get_items() == [item1, item2]
    assert Rule.get_items(type=BaseValueItem) == [item1, item2]
    assert Rule.get_items(type=(BaseValueItem, Item)) == [item1, item2]

    assert Rule.get_items(type=Item) == [item2]
Beispiel #8
0
    def get_create_item(cls, name: str, initial_value=None) -> 'MqttItem':
        """Creates a new item in HABApp and returns it or returns the already existing one with the given name

        :param name: item name
        :param initial_value: state the item will have if it gets created
        :return: item
        """
        assert isinstance(name, str), type(name)

        try:
            item = Items.get_item(name)
        except Items.ItemNotFoundException:
            item = cls(name, initial_value)
            Items.add_item(item)

        assert isinstance(item, cls), f'{cls} != {type(item)}'
        return item
def test_add(clean_reg):
    added = Item('test')
    Items.add_item(added)
    assert Items.item_exists('test')

    # adding the same item multiple times will not cause an exception
    Items.add_item(added)
    Items.add_item(added)

    # adding a new item -> exception
    with pytest.raises(Items.ItemAlreadyExistsError):
        Items.add_item(Item('test'))
def test_search_oh():
    item1 = OpenhabItem('oh_item_1', tags=frozenset(['tag1', 'tag2', 'tag3']),
                        groups=frozenset(['grp1', 'grp2']), metadata={'meta1': MetaData('meta_v1')})
    item2 = SwitchItem('oh_item_2', tags=frozenset(['tag1', 'tag2', 'tag4']),
                       groups=frozenset(['grp2', 'grp3']), metadata={'meta2': MetaData('meta_v2', config={'a': 'b'})})
    item3 = Item('item_2')

    assert Rule.get_items() == []

    Items.add_item(item1)
    Items.add_item(item2)
    Items.add_item(item3)

    assert Rule.get_items() == [item1, item2, item3]
    assert Rule.get_items(tags='tag2') == [item1, item2]
    assert Rule.get_items(tags='tag4') == [item2]

    assert Rule.get_items(groups='grp1') == [item1]
    assert Rule.get_items(groups='grp2') == [item1, item2]

    assert Rule.get_items(groups='grp1', tags='tag1') == [item1]
    assert Rule.get_items(groups='grp2', tags='tag4') == [item2]

    assert Rule.get_items(metadata='meta1') == [item1]
    assert Rule.get_items(metadata='meta2') == [item2]
    assert Rule.get_items(metadata=r'meta\d') == [item1, item2]

    assert Rule.get_items(metadata_value='meta_v1') == [item1]
    assert Rule.get_items(metadata_value='meta_v2') == [item2]
    assert Rule.get_items(metadata_value=r'meta_v\d') == [item1, item2]
    assert Rule.get_items(groups='grp1', metadata_value=r'meta_v\d') == [item1]