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_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_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_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_send_change_command_to_update(self): class MockOhRest(OhRest): def __init__(self): super().__init__(SetupTest.get_config()) self.send_type = None pass def _req_post(self, uri_path: str, payload=None) -> None: self.send_type = 'post' def _req_put(self, uri_path: str, payload=None) -> None: self.send_type = 'put' def clear(self): self.send_type = None channel = Channel.create_item('abc') rest = MockOhRest() rest.clear() data = OhSendData(OhSendFlags.COMMAND, channel, 123) rest.send(data) self.assertEqual('post', rest.send_type) rest.clear() data = OhSendData(OhSendFlags.COMMAND, channel, None) rest.send(data) self.assertEqual('put', rest.send_type)
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)
def _fill_event_from_group(event: 'OhEvent', json_data): channel_type = OhEvent.get_channel_type(event.notification_type) channel_name = OhEvent.extract_group_name(json_data.get('topic')) event.channel = Channel.create(channel_type, channel_name) # embedded structure as string! payload_text = json_data.get('payload') if payload_text: payload = json.loads(payload_text) state_type = payload.get('type') state_value = payload.get('value') event.state = State.convert(state_type, state_value)
def get_channel(self): if self.channel is None: raise ValueError('no channel') if self.flags & OhSendFlags.CHANNEL_AS_ITEM: if isinstance(self.channel, str): channel = Channel.create_item(self.channel) return channel raise ValueError() if isinstance(self.channel, Channel): return self.channel raise ValueError()
def _import_newer_state(self, channel: Channel, state_new: State) -> bool: if not channel or not channel.is_valid(): raise OhIllegalChannelException(channel) with self._lock_state: state = self._states.get(channel) if state: changed = state.import_newer_state(state_new) else: state_clone = copy.deepcopy(state_new) self._states[channel] = state_clone changed = True # _logger.debug('queue _import_newer_state: %s | %s', channel, changed) return changed
def create_from_thing_json(json_data: dict): event = OhEvent.create_empty() event.notification_type = OhNotificationType.THING_CHANGE channel_name = json_data.get('UID') event.channel = Channel.create(ChannelType.THING, channel_name) state_value = None status_info = json_data.get('statusInfo') if status_info: state_value = status_info.get('status') event.state = State.convert(StateType.THING_STATUS.name, state_value) return event
def create_from_state_json(json_data: dict, channel_type: ChannelType): event = OhEvent.create_empty() if channel_type == ChannelType.GROUP: event.notification_type = OhNotificationType.GROUP_CHANGE else: event.notification_type = OhNotificationType.ITEM_CHANGE channel_name = json_data.get('name') event.channel = Channel.create(channel_type, channel_name) state_type = json_data.get('type') state_value = json_data.get('state') event.state = State.convert(state_type, state_value) return event
def register_oh_listener(self, channel: Channel, listeners) -> None: if not channel or not channel.is_valid(): raise OhIllegalChannelException(channel) if not listeners: raise DispatcherException('invalid listener (None)!') listener = ActionListener() listener.channel = channel listener.listener = listeners listener.type = type with self._lock_channel_listeners: listeners = self._channel_listeners.get(channel) if not listeners: listeners = [] self._channel_listeners[channel] = listeners listeners.append(listener)
def _fill_event_from_thing(event: 'OhEvent', json_data): channel_type = OhEvent.get_channel_type(event.notification_type) channel_name = OhEvent.extract_item_name(json_data.get('topic')) event.channel = Channel.create(channel_type, channel_name) # embedded structure as string! payload_text = json_data.get('payload') if payload_text: payload = json.loads(payload_text) if isinstance(payload, list): payload_inner = payload[0] else: payload_inner = payload state_value = payload_inner.get('status') event.state = State.convert(StateType.THING_STATUS.name, state_value)
def test_fetch_thing(self): rest = OhRest(SetupTest.get_config()) time_start_loading = datetime.datetime.now() # noinspection PyPep8 json_data = { 'statusInfo': { 'status': 'ONLINE', 'statusDetail': 'NONE' }, 'editable': False, 'label': 'Homematic Bridge', 'configuration': { 'cuxdPort': 8701, 'socketMaxAlive': 900, 'installModeDuration': 60, 'reconnectInterval': 3600, 'timeout': 15, 'hmIpPort': 2010, 'discoveryTimeToLive': -1, 'wiredPort': 2000, 'gatewayType': 'ccu', 'callbackHost': '127.0.0.1', 'groupPort': 9292, 'gatewayAddress': '127.0.0.1', 'unpairOnDeletion': False, 'rfPort': 2001 }, 'properties': { 'serialNumber': 'NEQ1327832', 'firmwareVersion': '2.29.23.20171118', 'modelId': 'CCU2' }, 'UID': 'homematic:bridge:rhm', 'thingTypeUID': 'homematic:bridge', 'channels': [] } # noqa ev_out = rest._fetch_thing(time_start_loading, json_data) channel = Channel.create(ChannelType.THING, 'homematic:bridge:rhm') state = State.create(StateType.THING_STATUS, ThingStatusValue.ONLINE) ev_cmp = OhEvent.create(OhNotificationType.THING_CHANGE, channel, state) self.check_fetch_event(ev_out, ev_cmp)
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 test_eq(self): orig = Channel() orig.type = ChannelType.GROUP orig.name = 'hgffc' comp = copy.deepcopy(orig) self.assertTrue(orig == comp) comp = copy.deepcopy(orig) comp.type = ChannelType.ITEM self.assertTrue(orig != comp) comp = copy.deepcopy(orig) comp.name = orig.name + '2' self.assertTrue(orig != comp) startup = Channel.create_startup() self.assertEqual(startup.type, ChannelType.STARTUP) comp = Channel.create_startup() self.assertEqual(startup, comp) comp.name = 'xx' self.assertEqual(startup, comp)
def create_startup_action() -> 'Action': action = Action() action.channel = Channel.create_startup() return action
def get_item_state_value(self, channel_name: str): channel = Channel.create(ChannelType.ITEM, channel_name) state = self.get_state(channel) if state: return state.value return None
def get_item_state(self, channel_name: str) -> State: channel = Channel.create(ChannelType.ITEM, channel_name) state = self.get_state(channel) return state
def test_is_valid(self): channel = Channel.create(ChannelType.ITEM, 'dummyNumber') out = channel.is_valid() self.assertTrue(out) channel = Channel() channel.type = None channel.name = 'dummyNumber' out = channel.is_valid() self.assertFalse(out) channel = Channel() channel.type = ChannelType.ITEM channel.name = None out = channel.is_valid() self.assertFalse(out)