def push_action(self, root_action: Action) -> None: if not root_action or not root_action.is_valid(): raise OhIllegalActionException(root_action) max_queued_actions = 1000 count_queued_actions = self._action_queue.qsize() if count_queued_actions > max_queued_actions: raise DispatcherException('max queued actions exceeded ({} > {})!' .format(count_queued_actions, max_queued_actions)) if root_action.listener is None: with self._lock_channel_listeners: listeners = self._channel_listeners.get(root_action.channel) if listeners: for listener in listeners: action = copy.deepcopy(root_action) action.listener = listener.listener self._action_queue.put(action) else: listener = root_action.listener root_action.listener = None action = copy.deepcopy(root_action) action.listener = listener root_action.listener = listener self._action_queue.put(action)
def test_dispatch_action(self): dispatcher = Dispatcher() checker = DispatchCheckerRule(dispatcher) channel = Channel.create(ChannelType.ITEM, 'dummyNumber') checker.subscribe_channel_actions(channel) action_in = Action() action_in.channel = channel action_in.state_new = State.create(StateType.DECIMAL, 3) action_in.notification_type = OhNotificationType.ITEM_COMMAND self.assertTrue(len(checker.notifications) == 0) something_processed = dispatcher.dispatch() self.assertFalse(something_processed) self.assertTrue(len(checker.notifications) == 0) dispatcher.push_action(action_in) something_processed = dispatcher.dispatch() self.assertTrue(something_processed) self.assertTrue(len(checker.notifications) == 1) action_out = checker.notifications[0] action_out.listener = None # compare! compare = (action_in == action_out) self.assertTrue(compare)
def test_eq(self): orig = Action() orig.channel = Channel.create(ChannelType.ITEM, 'channel') orig.state_old = State.create(StateType.DECIMAL, 2.2) orig.state_new = State.create(StateType.DECIMAL, 4.4) orig.notification_type = OhNotificationType.ITEM_COMMAND comp = copy.deepcopy(orig) self.assertTrue(orig == comp) self.assertTrue(orig is not None) self.assertTrue(orig != 1) comp = copy.deepcopy(orig) orig.channel = Channel.create(ChannelType.ITEM, 'channel2') self.assertTrue(orig != comp) comp = copy.deepcopy(orig) orig.state_old = State.create(StateType.DECIMAL, 2.23) self.assertTrue(orig != comp) comp = copy.deepcopy(orig) orig.state_new = State.create(StateType.DECIMAL, 2.23) self.assertTrue(orig != comp) comp = copy.deepcopy(orig) orig.notification_type = OhNotificationType.ITEM_CHANGE self.assertTrue(orig != comp)
def test_notify_action(self): expected_num = 2 self.mock_gateway.set_state( Channel.create_item(SampleRule.ITEM_DUMMY_1), State.create(StateType.DECIMAL, expected_num)) self.mock_gateway.set_state( Channel.create_item(SampleRule.ITEM_DUMMY_2), State.create(StateType.DECIMAL, None)) self.mock_gateway.set_state( Channel.create_item(SampleRule.ITEM_STRING), State.create(StateType.STRING, None)) action = Action.create_cron_action(SampleRule.CRON_NAME) self.rule.notify_action(action) self.assertEqual(2, len(self.mock_gateway.sent_actions_list)) self.assertEqual(2, len(self.mock_gateway.sent_actions_channel_dict)) value_str = self.mock_gateway.get_last_channel_data( Channel.create_item(SampleRule.ITEM_STRING)) value_num = self.mock_gateway.get_last_channel_data( Channel.create_item(SampleRule.ITEM_DUMMY_2)) self.assertTrue(value_str is not None) self.assertEqual(expected_num, value_num)
def test_should_be_published(self): orig = Action() orig.channel = Channel.create(ChannelType.ITEM, 'channel') orig.state_old = State.create(StateType.DECIMAL, 2.2) orig.state_new = State.create(StateType.DECIMAL, 2.2) orig.notification_type = OhNotificationType.ITEM_CHANGE comp = copy.deepcopy(orig) out = comp.should_be_published() self.assertFalse(out) comp = copy.deepcopy(orig) comp.notification_type = OhNotificationType.ITEM_COMMAND out = comp.should_be_published() self.assertTrue(out) comp = copy.deepcopy(orig) comp.state_new = State.create(StateType.DECIMAL, 2.3) out = comp.should_be_published() self.assertTrue(out) comp = copy.deepcopy(orig) comp.channel = Channel.create(ChannelType.CRON, 'channel') out = comp.should_be_published() self.assertTrue(out)
def test_notify_action_not_connected(self): self.mock_gateway.mock_is_connected = False expected_num = 2 self.mock_gateway.set_state( Channel.create_item(SampleRule.ITEM_DUMMY_1), State.create(StateType.DECIMAL, expected_num)) action = Action.create_cron_action(SampleRule.CRON_NAME) self.rule.notify_action(action) self.assertEqual(0, len(self.mock_gateway.sent_actions_list)) self.assertEqual(0, len(self.mock_gateway.sent_actions_channel_dict))
def push_event(self, event: OhEvent) -> None: if not event or not event.is_valid(): raise OhIllegalEventException(event) # _logger.debug('push_event - in: %s', event) if event.notification_type == OhNotificationType.RELOAD: self._cache_states_notified_reload = datetime.datetime.now() else: action = Action.create_from_event(event) action.state_old = self.get_state(action.channel) # copied action self._import_newer_state(action.channel, action.state_new) if action.should_be_published(): self._dispatcher.push_action(action)
def test_dispatch_cron(self): dispatcher = Dispatcher() checker = DispatchCheckerRule(dispatcher) self.assertTrue(len(checker.notifications) == 0) something_processed = dispatcher.dispatch() self.assertFalse(something_processed) self.assertTrue(len(checker.notifications) == 0) cron_key = 'cron1' cron_job = schedule.every().second checker.subscribe_cron_actions(cron_key, cron_job) max_loop = 8 while True: time.sleep(0.2) print('loop ({})'.format(max_loop)) something_processed = dispatcher.dispatch_skip_cron(1) # waid 1ms if something_processed: break if max_loop < 0: break max_loop -= 1 time.sleep(0.2) self.assertTrue(something_processed) self.assertTrue(len(checker.notifications) >= 1) action_out = checker.notifications[0] print('test - action_out: ', action_out) action_out.listener = None # compare! action_cmp = Action() action_cmp.channel = Channel.create(ChannelType.CRON, cron_key) compare = (action_cmp == action_out) self.assertTrue(compare)
def job_closure(): action = Action.create_cron_action(cron_key) action.listener = listener instance._action_queue.put(action) # no protected access, just a closure
def test_repr(self): # no crash print(Action()) print(Action.create_cron_action('cron1')) print(Action.create_startup_action())
def test_is_valid(self): orig = Action() orig.channel = Channel.create(ChannelType.ITEM, 'channel') orig.state_old = State.create(StateType.DECIMAL, 2.2) orig.state_new = State.create(StateType.DECIMAL, 2.2) orig.notification_type = OhNotificationType.ITEM_CHANGE cron = Action() cron.channel = Channel.create(ChannelType.CRON, 'channel') cron.state_old = None cron.state_new = None cron.notification_type = None startup = Action.create_startup_action() comp = copy.deepcopy(orig) out = comp.is_valid() self.assertTrue(out) comp = copy.deepcopy(orig) comp.state_old = None out = comp.is_valid() self.assertTrue(out) comp = copy.deepcopy(cron) out = comp.is_valid() self.assertTrue(out) comp = copy.deepcopy(orig) comp.channel.name = None out = comp.is_valid() self.assertFalse(out) comp = copy.deepcopy(orig) comp.state_new = None out = comp.is_valid() self.assertFalse(out) comp = copy.deepcopy(orig) comp.notification_type = None out = comp.is_valid() self.assertFalse(out) out = startup.is_valid() self.assertTrue(out)