async def test_watch_update(parent_rule: DummyRule, event_bus: TmpEventBus, sync_worker, caplog): for meth in ('watch_update', 'watch_change'): cb = MagicMock() cb.__name__ = 'MockName' secs = 0.2 i = Item('test') func = getattr(i, meth) func(secs / 2) w = func(timedelta(seconds=secs)) w.listen_event(cb) i.post_value(1) await asyncio.sleep(0.3) cb.assert_called_once() assert isinstance( cb.call_args[0][0], ItemNoUpdateEvent if meth == 'watch_update' else ItemNoChangeEvent) assert cb.call_args[0][0].name == 'test' assert cb.call_args[0][0].seconds == secs
def map_items(name, openhab_type: str, openhab_value: str): assert isinstance(openhab_type, str), type(openhab_type) assert isinstance(openhab_value, str), type(openhab_value) value: typing.Optional[str] = openhab_value if openhab_value == 'NULL' or openhab_value == 'UNDEF': value = None # Quantity types are like this: Number:Temperature and have a unit set: "12.3 °C". # We have to remove the dimension from the type and remove the unit from the value if ':' in openhab_type: openhab_type = openhab_type[:openhab_type.find(':')] # if the item is not initialized its None and has no dimension if value is not None: value, _ = QuantityValue.split_unit(value) # Specific classes if openhab_type == "Switch": return SwitchItem(name, value) if openhab_type == "Contact": return ContactItem(name, value) if openhab_type == "Rollershutter": if value is None: return RollershutterItem(name, value) return RollershutterItem(name, float(value)) if openhab_type == "Dimmer": return DimmerItem(name, value) if openhab_type == "Number": if value is None: return NumberItem(name, value) # Number items can be int or float try: return NumberItem(name, int(value)) except ValueError: return NumberItem(name, float(value)) if openhab_type == "DateTime": if value is None: return Item(name, value) dt = datetime.datetime.strptime(value.replace('+', '000+'), '%Y-%m-%dT%H:%M:%S.%f%z') # all datetimes from openhab have a timezone set so we can't easily compare them # --> TypeError: can't compare offset-naive and offset-aware datetimes dt = dt.astimezone(tz=None) # Changes datetime object so it uses system timezone dt = dt.replace(tzinfo=None) # Removes timezone awareness return Item(name, dt) if openhab_type == "Color": if value is None: return ColorItem(name) return ColorItem(name, *(float(k) for k in value.split(','))) return Item(name, value)
async def test_multiple_add(parent_rule: DummyRule): i = Item('test') w1 = i.watch_change(5) w2 = i.watch_change(5) assert w1 is w2 w1.fut.cancel() w2 = i.watch_change(5) assert w1 is not w2
def test_multiple_add(monkeypatch): monkeypatch.setattr(HABApp.rule, 'get_parent_rule', lambda: DummyRule(), raising=True) i = Item('test') w1 = i.watch_change(5) w2 = i.watch_change(5) assert w1 is w2 w1._fut.cancel() w2 = i.watch_change(5) assert w1 is not w2
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]
def test_complex_event_unpack(event_bus: EventBus): """Test that the ComplexEventValue get properly unpacked""" m = MagicMock() assert not m.called item = Item.get_create_item('test_complex') listener = EventBusListener( item.name, wrappedfunction.WrappedFunction(m, name='test')) EventBus.add_listener(listener) with SyncWorker(): item.post_value(ComplexEventValue('ValOld')) item.post_value(ComplexEventValue('ValNew')) # assert that we have been called with exactly one arg for k in m.call_args_list: assert len(k[0]) == 1 arg0 = m.call_args_list[0][0][0] arg1 = m.call_args_list[1][0][0] arg2 = m.call_args_list[2][0][0] arg3 = m.call_args_list[3][0][0] # Events for first post_value assert vars(arg0) == vars(ValueUpdateEvent(item.name, 'ValOld')) assert vars(arg1) == vars(ValueChangeEvent(item.name, 'ValOld', None)) # Events for second post_value assert vars(arg2) == vars(ValueUpdateEvent(item.name, 'ValNew')) assert vars(arg3) == vars(ValueChangeEvent(item.name, 'ValNew', 'ValOld'))
def item_events(self, changes=False, secs=5, values=[]): self.secs = secs self.watch_item = Item.get_create_item(get_random_name()) (self.watch_item.watch_change if changes else self.watch_item.watch_update)(secs) event = ItemNoUpdateEvent if not changes else ItemNoChangeEvent self.ts_set = 0 listener = self.listen_event(self.watch_item, self.check_event, event) for step, value in enumerate(values): if step: time.sleep(0.2) self.ts_set = time.time() self.watch_item.set_value(value) with EventWaiter(self.watch_item.name, event, secs + 2, check_value=False) as w: w.wait_for_event(value) if not w.events_ok: listener.cancel() return w.events_ok listener.cancel() return True
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_time_change(self): i = Item('test') i.set_value('test') i._last_change = datetime.now(tz=pytz.utc) - timedelta(seconds=5) i._last_update = datetime.now(tz=pytz.utc) - timedelta(seconds=5) i.set_value('test1') self.assertGreater( i._last_update, datetime.now(tz=pytz.utc) - timedelta(milliseconds=100)) self.assertGreater( i._last_change, datetime.now(tz=pytz.utc) - timedelta(milliseconds=100))
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 item_events(self, changes=False, secs=5, values=[]): item_name = get_random_name() self.secs = secs self.watch_item = Item.get_create_item(item_name) watcher = (self.watch_item.watch_change if changes else self.watch_item.watch_update)(secs) event = ItemNoUpdateEvent if not changes else ItemNoChangeEvent listener = self.listen_event(self.watch_item, self.check_event, event) def _run(): self.ts_set = 0 for step, value in enumerate(values): if step: time.sleep(0.2) self.ts_set = time.time() self.watch_item.set_value(value) with EventWaiter(self.watch_item.name, event, secs + 2, check_value=False) as w: w.wait_for_event(value) if not w.events_ok: listener.cancel() return w.events_ok return True if not _run(): return False HABApp.core.Items.pop_item(item_name) assert not HABApp.core.Items.item_exists(item_name) time.sleep(1) self.watch_item = Item.get_create_item(item_name) if not _run(): return False listener.cancel() watcher.cancel() return True
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]
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 item_events(self, changes=False, secs=5, values=[]): item_name = get_random_name('HABApp') self.watch_item = Item.get_create_item(item_name) self.secs = secs watcher = (self.watch_item.watch_change if changes else self.watch_item.watch_update)(secs) event = ItemNoUpdateEvent if not changes else ItemNoChangeEvent listener = self.listen_event(self.watch_item, self.check_event, event) try: self._run(values, event) HABApp.core.Items.pop_item(item_name) assert not HABApp.core.Items.item_exists(item_name) time.sleep(0.5) self.watch_item = Item.get_create_item(item_name) self._run(values, event) finally: listener.cancel() watcher.cancel() return None
def test_time_change(self): i = Item('test') i.set_value('test') i._last_change.set(pd_now(UTC) - timedelta(seconds=5)) i._last_update.set(pd_now(UTC) - timedelta(seconds=5)) i.set_value('test1') self.assertGreater(i._last_update.dt, pd_now(UTC) - timedelta(milliseconds=100)) self.assertGreater(i._last_change.dt, pd_now(UTC) - timedelta(milliseconds=100))
def item_events(self, changes=False, secs=5, values=[]): watch_item = Item.get_create_item('watch_item', values[0]) event = ValueNoUpdateEvent if not changes else ValueNoChangeEvent def cb(event: ValueNoUpdateEvent): assert event.name == watch_item.name, f'Wrong name: {event.name} != {watch_item.name}' assert event.seconds == secs, f'Wrong seconds: {event.seconds} != {secs}' self.item_watch_and_listen(watch_item.name, secs, cb, changes) for step, value in enumerate(values): watch_item.set_value(value) with EventWaiter(watch_item.name, event, secs + 2) as w: w.wait_for_event(value) if not w.events_ok: return w.events_ok return True
def trigger_event(self): self.watch_item = Item.get_create_item(get_random_name()) listener = self.watch_item.listen_event(self.check_event, ValueUpdateEvent) self.run.at(1, HABApp.core.EventBus.post_event, self.watch_item.name, ValueUpdateEvent(self.watch_item.name, 123)) with EventWaiter(self.watch_item.name, ValueUpdateEvent, 2, check_value=True) as w: w.wait_for_event(123) if not w.events_ok: listener.cancel() return w.events_ok listener.cancel() return True
def test_time_update(self): i = Item('test') i.set_value('test') i._last_change.set(datetime.now(tz=pytz.utc) - timedelta(seconds=5), events=False) i._last_update.set(datetime.now(tz=pytz.utc) - timedelta(seconds=5), events=False) i.set_value('test') self.assertGreater( i._last_update.dt, datetime.now(tz=pytz.utc) - timedelta(milliseconds=100)) self.assertLess( i._last_change.dt, datetime.now(tz=pytz.utc) - timedelta(milliseconds=100))
def test_repr(self): i = Item('test') self.assertGreater(len(str(i)), 23)
def set_up(self): self.watch_item = Item.get_create_item(get_random_name('HABApp')) self.listener = self.watch_item.listen_event(self.check_event, ValueUpdateEvent)