示例#1
0
    def test_master_output_event(self):
        events = []

        def _on_event(master_event):
            events.append(master_event)

        classic = get_classic_controller_dummy()
        pubsub = get_pubsub()
        pubsub.subscribe_master_events(PubSub.MasterTopics.OUTPUT, _on_event)
        classic._output_config = {
            0: OutputDTO(id=0),
            1: OutputDTO(id=1),
            2: OutputDTO(id=2, room=3)
        }

        pubsub._publish_all_events()
        events = []
        classic._on_master_output_event({'outputs': [(0, 0), (2, 5)]})
        pubsub._publish_all_events()
        assert [
            MasterEvent('OUTPUT_STATUS', {
                'id': 0,
                'status': True,
                'dimmer': 0
            }),
            MasterEvent('OUTPUT_STATUS', {
                'id': 1,
                'status': False
            }),
            MasterEvent('OUTPUT_STATUS', {
                'id': 2,
                'status': True,
                'dimmer': 5
            })
        ] == events
示例#2
0
    def test_eeprom_events(self):
        """ Test read. """
        controller = get_eeprom_controller_dummy({0: bytearray([0] * 256),
                                                  1: bytearray([0] * 2) + bytearray(b'hello') + bytearray([0] * 249)})
        model = controller.read(Model1, 0)
        self.assertEqual(0, model.id)
        self.assertEqual('hello' + '\x00' * 95, model.name)

        events = []

        def handle_events(master_event):
            events.append(master_event)

        get_pubsub().subscribe_master_events(PubSub.MasterTopics.EEPROM, handle_events)
        controller.invalidate_cache()
        get_pubsub()._publish_all_events()
        self.assertEqual([
            MasterEvent(MasterEvent.Types.EEPROM_CHANGE, {})
        ], events)
        controller.activate()
        get_pubsub()._publish_all_events()
        self.assertEqual([
            MasterEvent(MasterEvent.Types.EEPROM_CHANGE, {}),
            MasterEvent(MasterEvent.Types.EEPROM_CHANGE, {})
        ], events)
    def test_master_output_event(self):
        events = []

        def _on_event(master_event):
            events.append(master_event)

        self.pubsub.subscribe_master_events(PubSub.MasterTopics.OUTPUT, _on_event)

        events = []
        self.controller._handle_event({'type': 0, 'device_nr': 0, 'action': 0, 'data': bytearray([255, 0, 0, 0])})
        self.controller._handle_event({'type': 0, 'device_nr': 2, 'action': 1, 'data': bytearray([100, 2, 0xff, 0xfe])})
        self.pubsub._publish_all_events()
        self.assertEqual([MasterEvent(MasterEvent.Types.OUTPUT_STATUS, {'id': 0, 'status': False, 'dimmer': 255, 'ctimer': 0}),
                          MasterEvent(MasterEvent.Types.OUTPUT_STATUS, {'id': 2, 'status': True, 'dimmer': 100, 'ctimer': 65534})], events)
    def test_subscribe_input_events(self):
        consumer_list = []

        def new_consumer(*args):
            consumer = BackgroundConsumer(*args)
            consumer_list.append(consumer)
            return consumer

        subscriber = mock.Mock()
        with mock.patch.object(gateway.hal.master_controller_core, 'BackgroundConsumer',
                               side_effect=new_consumer) as new_consumer:
            controller = MasterCoreController()
        self.pubsub.subscribe_master_events(PubSub.MasterTopics.INPUT, subscriber.callback)

        new_consumer.assert_called()
        event_data = {'type': 1, 'action': 1, 'device_nr': 2,
                      'data': {}}
        with mock.patch.object(Queue, 'get', return_value=event_data):
            consumer_list[0].deliver()
        self.pubsub._publish_all_events()
        expected_event = MasterEvent.deserialize({'type': 'INPUT_CHANGE',
                                                  'data': {'id': 2,
                                                           'status': True,
                                                           'location': {'room_id': 255}}})
        subscriber.callback.assert_called_with(expected_event)
示例#5
0
    def test_subscribe_input_events(self):
        consumer_list = []

        def new_consumer(*args):
            consumer = BackgroundConsumer(*args)
            consumer_list.append(consumer)
            return consumer

        subscriber = mock.Mock()
        with mock.patch.object(gateway.hal.master_controller_classic, 'BackgroundConsumer',
                               side_effect=new_consumer) as new_consumer:
            controller = get_classic_controller_dummy()
            pubsub = get_pubsub()
            controller._register_version_depending_background_consumers()
            controller._input_config = {1: InputDTO(id=1)}  # TODO: cleanup
            pubsub.subscribe_master_events(PubSub.MasterTopics.INPUT, subscriber.callback)
            new_consumer.assert_called()
            consumer_list[-2].deliver({'input': 1})
            pubsub._publish_all_events()
            try:
                consumer_list[-2]._consume()
            except:
                pass  # Just ensure it has at least consumed once
            expected_event = MasterEvent.deserialize({'type': 'INPUT_CHANGE',
                                                      'data': {'id': 1,
                                                               'status': True,
                                                               'location': {'room_id': 255}}})
            subscriber.callback.assert_called_with(expected_event)
    def test_refresh(self):
        from gateway.hal.master_controller_core import MasterCoreEvent, MasterInputState
        state = MasterInputState(interval=10)
        core_events = [
            MasterCoreEvent({'type': 1, 'action': 1, 'device_nr': 1, 'data': {}}),
            MasterCoreEvent({'type': 1, 'action': 0, 'device_nr': 2, 'data': {}}),
        ]
        with mock.patch.object(time, 'time', return_value=30):
            for core_event in core_events:
                state.handle_event(core_event)
            self.assertTrue(state.should_refresh())
            events = state.refresh([0b00000110])
            self.assertEqual(1, len(events))
            expected_event = MasterEvent(event_type=MasterEvent.Types.INPUT_CHANGE,
                                         data={'id': 2,
                                               'status': True,
                                               'location': {'room_id': 255}})
            self.assertIn(expected_event, events)
            self.assertFalse(state.should_refresh())

            events = state.refresh([0b00000110])
            self.assertEqual([], events)

        with mock.patch.object(time, 'time', return_value=60):
            self.assertTrue(state.should_refresh())
示例#7
0
 def test_master_maintenance_event(self):
     controller = get_classic_controller_dummy()
     pubsub = get_pubsub()
     with mock.patch.object(controller._eeprom_controller, 'invalidate_cache') as invalidate:
         master_event = MasterEvent(MasterEvent.Types.MAINTENANCE_EXIT, {})
         pubsub.publish_master_event(PubSub.MasterTopics.MAINTENANCE, master_event)
         pubsub._publish_all_events()
         invalidate.assert_called()
示例#8
0
 def invalidate_cache(self):
     # type: () -> None
     """ Invalidate the cache, this should happen when maintenance mode was used. """
     self._eeprom_file.invalidate_cache()
     self.dirty = True
     master_event = MasterEvent(MasterEvent.Types.EEPROM_CHANGE, {})
     self._pubsub.publish_master_event(PubSub.MasterTopics.EEPROM,
                                       master_event)
示例#9
0
 def test_eeprom_events(self):
     master_event = MasterEvent(MasterEvent.Types.EEPROM_CHANGE, {})
     with mock.patch.object(self.controller,
                            'invalidate_cache') as handle_event:
         self.pubsub.publish_master_event(PubSub.MasterTopics.EEPROM,
                                          master_event)
         self.pubsub._publish_all_events()
         handle_event.assert_called()
示例#10
0
 def test_master_eeprom_event(self):
     controller = get_classic_controller_dummy()
     controller._input_last_updated = 1603178386.0
     pubsub = get_pubsub()
     master_event = MasterEvent(MasterEvent.Types.EEPROM_CHANGE, {})
     pubsub.publish_master_event(PubSub.MasterTopics.EEPROM, master_event)
     pubsub._publish_all_events()
     assert controller._input_last_updated == 0.0
    def test_master_shutter_refresh(self):
        events = []

        def _on_event(master_event):
            events.append(master_event)

        self.pubsub.subscribe_master_events(PubSub.MasterTopics.SHUTTER, _on_event)

        output_status = [{'device_nr': 0, 'status': False, 'dimmer': 0},
                         {'device_nr': 1, 'status': False, 'dimmer': 0},
                         {'device_nr': 10, 'status': False, 'dimmer': 0},
                         {'device_nr': 11, 'status': False, 'dimmer': 0}]
        with mock.patch.object(gateway.hal.master_controller_core, 'ShutterConfiguration',
                               side_effect=get_core_shutter_dummy), \
             mock.patch.object(self.controller, 'load_output_status', return_value=output_status):
            events = []
            self.controller._refresh_shutter_states()
            self.pubsub._publish_all_events()
            assert [MasterEvent('SHUTTER_CHANGE', {'id': 1, 'status': 'stopped', 'location': {'room_id': 255}})] == events

        output_status = [{'device_nr': 0, 'status': False, 'dimmer': 0},
                         {'device_nr': 1, 'status': True, 'dimmer': 0},
                         {'device_nr': 10, 'status': True, 'dimmer': 0},
                         {'device_nr': 11, 'status': False, 'dimmer': 0}]
        with mock.patch.object(gateway.hal.master_controller_core, 'ShutterConfiguration',
                               side_effect=get_core_shutter_dummy), \
             mock.patch.object(self.controller, 'load_output_status', return_value=output_status):
            events = []
            self.controller._refresh_shutter_states()
            self.pubsub._publish_all_events()
            assert [MasterEvent('SHUTTER_CHANGE', {'id': 1, 'status': 'going_up', 'location': {'room_id': 255}})] == events

        output_status = [{'device_nr': 0, 'status': False, 'dimmer': 0},
                         {'device_nr': 1, 'status': True, 'dimmer': 0},
                         {'device_nr': 10, 'status': False, 'dimmer': 0},
                         {'device_nr': 11, 'status': True, 'dimmer': 0}]
        with mock.patch.object(gateway.hal.master_controller_core, 'ShutterConfiguration',
                               side_effect=get_core_shutter_dummy), \
             mock.patch.object(self.controller, 'load_output_status', return_value=output_status):
            events = []
            self.controller._refresh_shutter_states()
            self.pubsub._publish_all_events()
            assert [MasterEvent('SHUTTER_CHANGE', {'id': 1, 'status': 'going_down', 'location': {'room_id': 255}})] == events
示例#12
0
 def activate(self):
     """
     Activate a change in the Eeprom. The master will read the eeprom
     and adjust the current settings.
     """
     logger.info('EEPROM - Activate')
     self._master_communicator.do_command(activate_eeprom(), {'eep': 0})
     master_event = MasterEvent(MasterEvent.Types.EEPROM_CHANGE, {})
     self._pubsub.publish_master_event(PubSub.MasterTopics.EEPROM,
                                       master_event)
示例#13
0
    def test_master_output_event(self):
        events = []

        def _on_event(master_event):
            events.append(master_event)

        self.pubsub.subscribe_master_events(PubSub.MasterTopics.OUTPUT, _on_event)

        events = []
        self.controller._handle_event({'type': 0, 'device_nr': 0, 'action': 0, 'data': bytearray([255, 0, 0, 0])})
        self.controller._handle_event({'type': 0, 'device_nr': 2, 'action': 1, 'data': bytearray([100, 2, 0xff, 0xfe])})
        self.controller._handle_event({'type': 0, 'device_nr': 4, 'action': 2, 'data': bytearray([1, 0, 0, 0])})
        self.controller._handle_event({'type': 0, 'device_nr': 6, 'action': 2, 'data': bytearray([0, 0, 0, 0])})
        self.pubsub._publish_all_events()
        self.assertEqual([MasterEvent(MasterEvent.Types.OUTPUT_STATUS, {'state': OutputStateDTO(id=0, status=False, dimmer=255, ctimer=0)}),
                          MasterEvent(MasterEvent.Types.OUTPUT_STATUS, {'state': OutputStateDTO(id=2, status=True, dimmer=100, ctimer=65534)}),
                          MasterEvent(MasterEvent.Types.OUTPUT_STATUS, {'state': OutputStateDTO(id=4, locked=True)}),
                          MasterEvent(MasterEvent.Types.OUTPUT_STATUS, {'state': OutputStateDTO(id=6, locked=False)})],
                         events)
    def test_master_shutter_event(self):
        events = []

        def _on_event(master_event):
            events.append(master_event)

        self.pubsub.subscribe_master_events(PubSub.MasterTopics.SHUTTER, _on_event)

        self.controller._output_states = {0: OutputStateDTO(id=0, status=False),
                                          10: OutputStateDTO(id=10, status=False),
                                          11: OutputStateDTO(id=11, status=False)}
        self.controller._output_shutter_map = {10: 1, 11: 1}
        self.controller._shutter_status = {1: (False, False)}
        self.pubsub._publish_all_events()

        with mock.patch.object(gateway.hal.master_controller_core, 'ShutterConfiguration',
                               side_effect=get_core_shutter_dummy):
            events = []
            self.controller._handle_event({'type': 0, 'device_nr': 10, 'action': 0, 'data': [None, 0, 0, 0]})
            self.controller._handle_event({'type': 0, 'device_nr': 11, 'action': 0, 'data': [None, 0, 0, 0]})
            self.pubsub._publish_all_events()
            assert [] == events

            events = []
            self.controller._handle_event({'type': 0, 'device_nr': 10, 'action': 1, 'data': [None, 0, 0, 0]})
            self.pubsub._publish_all_events()
            assert [MasterEvent('SHUTTER_CHANGE', {'id': 1, 'status': 'going_up', 'location': {'room_id': 255}})] == events

            events = []
            self.controller._handle_event({'type': 0, 'device_nr': 11, 'action': 1, 'data': [None, 0, 0, 0]})
            self.pubsub._publish_all_events()
            assert [MasterEvent('SHUTTER_CHANGE', {'id': 1, 'status': 'stopped', 'location': {'room_id': 255}})] == events

            events = []
            self.controller._handle_event({'type': 0, 'device_nr': 10, 'action': 0, 'data': [None, 0, 0, 0]})
            self.pubsub._publish_all_events()
            assert [MasterEvent('SHUTTER_CHANGE', {'id': 1, 'status': 'going_down', 'location': {'room_id': 255}})] == events

            events = []
            self.controller._handle_event({'type': 0, 'device_nr': 11, 'action': 0, 'data': [None, 0, 0, 0]})
            self.pubsub._publish_all_events()
            assert [MasterEvent('SHUTTER_CHANGE', {'id': 1, 'status': 'stopped', 'location': {'room_id': 255}})] == events
示例#15
0
    def test_master_output_event(self):
        events = []

        def _on_event(master_event):
            events.append(master_event)

        classic = get_classic_controller_dummy()
        pubsub = get_pubsub()
        pubsub.subscribe_master_events(PubSub.MasterTopics.OUTPUT, _on_event)
        classic._output_config = {0: OutputDTO(id=0),
                                  1: OutputDTO(id=1),
                                  2: OutputDTO(id=2, room=3)}

        pubsub._publish_all_events()
        events = []
        classic._on_master_output_event({'outputs': [(0, 0), (2, 5)]})
        pubsub._publish_all_events()
        self.assertEqual(events, [MasterEvent('OUTPUT_STATUS', {'state': OutputStateDTO(id=0, status=True, dimmer=0)}),
                                  MasterEvent('OUTPUT_STATUS', {'state': OutputStateDTO(id=1, status=False)}),
                                  MasterEvent('OUTPUT_STATUS', {'state': OutputStateDTO(id=2, status=True, dimmer=5)})])
示例#16
0
    def stop_address_mode(self):
        # type: () -> None
        """ Stop address mode. """
        if not self.__address_mode:
            raise Exception("Not in address mode !")

        self.__address_mode_stop = True
        if self.__address_thread:
            self.__address_thread.join()
        self.__address_thread = None
        master_event = MasterEvent(MasterEvent.Types.POWER_ADDRESS_EXIT, {})
        self.__pubsub.publish_master_event(PubSub.MasterTopics.POWER, master_event)
示例#17
0
 def _handle_event(self, data):  # type: (Dict[str, Any]) -> None
     core_event = Event(data)
     if core_event.type == Event.Types.SYSTEM and core_event.data['type'] == Event.SystemEventTypes.EEPROM_ACTIVATE:
         if self._self_activated:
             # Ignore self-activations, since those changes are already in the EEPROM cache
             self._self_activated = False
             logger.info('Ignore EEPROM_ACTIVATE due to self-activation')
         else:
             # EEPROM might have been changed, so clear caches
             self.invalidate_cache()
             logger.info('Cache cleared: EEPROM_ACTIVATE')
         self._activation_event.set()
         master_event = MasterEvent(MasterEvent.Types.EEPROM_CHANGE, {})
         self._pubsub.publish_master_event(PubSub.MasterTopics.EEPROM, master_event)
示例#18
0
    def test_config_event(self):
        events = []

        def handle_events(gateway_event):
            events.append(gateway_event)

        self.pubsub.subscribe_gateway_events(PubSub.GatewayTopics.CONFIG,
                                             handle_events)
        master_event = MasterEvent(MasterEvent.Types.POWER_ADDRESS_EXIT, {})
        self.pubsub.publish_master_event(PubSub.MasterTopics.POWER,
                                         master_event)
        self.pubsub._publish_all_events()

        assert GatewayEvent(GatewayEvent.Types.CONFIG_CHANGE,
                            {'type': 'powermodule'}) in events
        assert len(events) == 1
示例#19
0
    def deactivate(self, join=True):
        # type: (bool) -> None
        logger.info('Deactivating maintenance mode')
        self._stopped = True
        if join and self._read_data_thread is not None:
            self._read_data_thread.join()
            self._read_data_thread = None
        self._master_communicator.stop_maintenance_mode()

        if self._maintenance_timeout_timer is not None:
            self._maintenance_timeout_timer.cancel()
            self._maintenance_timeout_timer = None

        if self._deactivated_sent is False:
            master_event = MasterEvent(MasterEvent.Types.MAINTENANCE_EXIT, {})
            self._pubsub.publish_master_event(PubSub.MasterTopics.MAINTENANCE, master_event)
            self._deactivated_sent = True
示例#20
0
    def test_address_mode(self):
        """ Test the address mode. """
        events = []

        def handle_events(master_event):
            events.append(master_event)

        self.pubsub.subscribe_master_events(PubSub.MasterTopics.POWER, handle_events)

        sad = power_api.set_addressmode(power_api.POWER_MODULE)
        sad_p1c = power_api.set_addressmode(power_api.P1_CONCENTRATOR)

        self.power_data.extend([
            sin(sad.create_input(power_api.BROADCAST_ADDRESS, 1, power_api.ADDRESS_MODE)),
            sin(sad_p1c.create_input(power_api.BROADCAST_ADDRESS, 2, power_api.ADDRESS_MODE)),
            sout(power_api.want_an_address(power_api.POWER_MODULE).create_output(0, 0)),
            sin(power_api.set_address(power_api.POWER_MODULE).create_input(0, 0, 1)),
            sout(power_api.want_an_address(power_api.ENERGY_MODULE).create_output(0, 0)),
            sin(power_api.set_address(power_api.ENERGY_MODULE).create_input(0, 0, 2)),
            sout(power_api.want_an_address(power_api.P1_CONCENTRATOR).create_output(0, 0)),
            sin(power_api.set_address(power_api.P1_CONCENTRATOR).create_input(0, 0, 3)),
            sout(bytearray()),  # Timeout read after 1 second
            sin(sad.create_input(power_api.BROADCAST_ADDRESS, 3, power_api.NORMAL_MODE)),
            sin(sad_p1c.create_input(power_api.BROADCAST_ADDRESS, 4, power_api.NORMAL_MODE))
        ])
        self.serial.start()
        self.communicator.start()

        self.assertEqual(self.store.get_free_address(), 1)

        self.communicator.start_address_mode()
        self.assertTrue(self.communicator.in_address_mode())
        self.pubsub._publish_all_events()
        time.sleep(0.5)
        assert [] == events

        self.communicator.stop_address_mode()
        self.pubsub._publish_all_events()
        assert MasterEvent(MasterEvent.Types.POWER_ADDRESS_EXIT, {}) in events
        assert len(events) == 1

        self.assertEqual(self.store.get_free_address(), 4)
        self.assertFalse(self.communicator.in_address_mode())
 def test_master_eeprom_event(self):
     master_event = MasterEvent(MasterEvent.Types.EEPROM_CHANGE, {})
     self.controller._output_last_updated = 1603178386.0
     self.pubsub.publish_master_event(PubSub.MasterTopics.EEPROM, master_event)
     self.pubsub._publish_all_events()
     assert self.controller._output_last_updated == 0
示例#22
0
    def test_output_master_change(self):
        events = []

        def on_change(gateway_event):
            events.append(gateway_event)

        self.pubsub.subscribe_gateway_events(PubSub.GatewayTopics.STATE,
                                             on_change)

        self.controller._cache.update_outputs(
            [OutputDTO(id=2),
             OutputDTO(id=40, module_type='D', room=3)])
        self.controller._handle_master_event(
            MasterEvent('OUTPUT_STATUS',
                        {'state': OutputStateDTO(id=2, status=False)}))
        self.controller._handle_master_event(
            MasterEvent(
                'OUTPUT_STATUS',
                {'state': OutputStateDTO(id=40, status=True, dimmer=100)}))
        self.pubsub._publish_all_events()

        events = []
        self.controller._handle_master_event(
            MasterEvent('OUTPUT_STATUS',
                        {'state': OutputStateDTO(id=2, status=True)}))
        self.controller._handle_master_event(
            MasterEvent('OUTPUT_STATUS',
                        {'state': OutputStateDTO(id=40, status=True)}))
        self.pubsub._publish_all_events()

        assert [
            GatewayEvent(
                'OUTPUT_CHANGE', {
                    'id': 2,
                    'status': {
                        'on': True,
                        'locked': False
                    },
                    'location': {
                        'room_id': 255
                    }
                })
        ] == events

        events = []
        self.controller._handle_master_event(
            MasterEvent('OUTPUT_STATUS',
                        {'state': OutputStateDTO(id=40, dimmer=50)}))
        self.pubsub._publish_all_events()
        assert [
            GatewayEvent(
                'OUTPUT_CHANGE', {
                    'id': 40,
                    'status': {
                        'on': True,
                        'value': 50,
                        'locked': False
                    },
                    'location': {
                        'room_id': 3
                    }
                })
        ] == events