Ejemplo n.º 1
0
    def test_master_event_failsafe(self):
        _ = self

        SetUpTestInjections(master_communicator=Mock(),
                            configuration_controller=Mock(),
                            eeprom_controller=Mock())

        master_controller = MasterClassicController()
        master_controller._shutter_config = {shutter.id: shutter for shutter in ShutterControllerTest.SHUTTER_CONFIG}
        master_controller._shutter_config.pop(0)

        # Got data for an unconfigured shutter. This should not raise.
        master_controller._update_from_master_state({'module_nr': 0, 'status': 0b00000000})
Ejemplo n.º 2
0
    def test_events_and_state(self):
        fakesleep.reset(0)
        calls = {}

        SetUpTestInjections(master_communicator=Mock(),
                            configuration_controller=Mock(),
                            eeprom_controller=Mock())

        master_controller = MasterClassicController()
        master_controller._master_version = (3, 143, 103)
        master_controller._shutter_config = {shutter.id: shutter for shutter in ShutterControllerTest.SHUTTER_CONFIG}
        SetUpTestInjections(master_controller=master_controller,
                            maintenance_controller=Mock())

        controller = ShutterController()
        controller.update_config(ShutterControllerTest.SHUTTER_CONFIG)

        def shutter_callback(event):
            calls.setdefault(event.data['id'], []).append(event.data['status']['state'])

        self.pubsub.subscribe_gateway_events(PubSub.GatewayTopics.STATE, shutter_callback)
        self.pubsub._publish_all_events()

        def validate(_shutter_id, _entry):
            self.pubsub._publish_all_events()
            self.assertEqual(controller._actual_positions.get(_shutter_id), _entry[0])
            self.assertEqual(controller._desired_positions.get(_shutter_id), _entry[1])
            self.assertEqual(controller._directions.get(_shutter_id), _entry[2])
            timer, state = controller._states.get(_shutter_id)
            self.assertEqual(timer, _entry[3][0])
            self.assertEqual(state, _entry[3][1])
            if len(_entry) == 4 or _entry[4]:
                self.assertEqual(calls[_shutter_id].pop(), _entry[3][1].upper())

        master_controller._update_from_master_state({'module_nr': 0, 'status': 0b00000000})
        self.pubsub._publish_all_events()
        for shutter_id in range(3):
            #                     +- actual position
            #                     |     +- desired position
            #                     |     |     +- direction                        +- state                     +- optional skip call check
            #                     v     v     v                                   v                            v
            validate(shutter_id, [None, None, ShutterEnums.Direction.STOP,  (0.0, ShutterEnums.State.STOPPED), False])

        ###################################################################################################
        # set stutters to a known initial state
        for shutter in self.SHUTTER_CONFIG:
            controller._directions[shutter.id] = ShutterEnums.Direction.UP
            controller._actual_positions[shutter.id] = 0
        ###################################################################################################

        for shutter_id in range(3):
            controller.shutter_down(shutter_id, None)
            self.pubsub._publish_all_events()

        time.sleep(20)

        master_controller._update_from_master_state({'module_nr': 0, 'status': 0b00011001})
        self.pubsub._publish_all_events()
        #                             +- actual position
        #                             |     +- desired position
        #                             |     |     +- direction                      +- state
        #                             v     v     v                                 v
        for shutter_id, entry in {0: [0, 99, ShutterEnums.Direction.DOWN, (20, ShutterEnums.State.GOING_DOWN)],
                                  1: [0, 99, ShutterEnums.Direction.DOWN,   (20, ShutterEnums.State.GOING_DOWN)],  # this shutter is inverted
                                  2: [0, 79,   ShutterEnums.Direction.DOWN, (20, ShutterEnums.State.GOING_DOWN)]}.items():
            validate(shutter_id, entry)
            self.pubsub._publish_all_events()

        time.sleep(50)  # Standard shutters will still be going down

        controller._actual_positions[2] = 20  # Simulate position reporting
        master_controller._update_from_master_state({'module_nr': 0, 'status': 0b00011000})  # First shutter motor stop
        self.pubsub._publish_all_events()
        #                             +- actual position
        #                             |     +- desired position
        #                             |     |     +- direction                      +- state                        +- optional skip call check
        #                             v     v     v                                 v                               v
        for shutter_id, entry in {0: [25, 99, ShutterEnums.Direction.STOP, (70, ShutterEnums.State.STOPPED)],
                                  1: [0, 99, ShutterEnums.Direction.DOWN,   (20, ShutterEnums.State.GOING_DOWN),   False],
                                  2: [20,   79,   ShutterEnums.Direction.DOWN, (20, ShutterEnums.State.GOING_DOWN), False]}.items():
            validate(shutter_id, entry)
            self.pubsub._publish_all_events()

        time.sleep(50)  # Standard shutters will be down now

        controller._actual_positions[2] = 50  # Simulate position reporting
        master_controller._update_from_master_state({'module_nr': 0, 'status': 0b00010000})  # Second shutter motor stop
        #                             +- actual position
        #                             |     +- desired position
        #                             |     |     +- direction                       +- state                        +- optional skip call check
        #                             v     v     v                                  v                               v
        for shutter_id, entry in {0: [25, 99, ShutterEnums.Direction.STOP,  (70, ShutterEnums.State.STOPPED),    False],
                                  1: [99, 99, ShutterEnums.Direction.STOP, (120, ShutterEnums.State.DOWN)],
                                  2: [50, 79,   ShutterEnums.Direction.DOWN,  (20, ShutterEnums.State.GOING_DOWN), False]}.items():
            validate(shutter_id, entry)

        time.sleep(10)

        controller._actual_positions[2] = 50  # Simulate position reporting
        master_controller._update_from_master_state({'module_nr': 0, 'status': 0b00000000})  # Third motor stopped
        #                             +- actual position
        #                             |     +- desired position
        #                             |     |     +- direction                      +- state                      +- optional skip call check
        #                             v     v     v                                 v                             v
        for shutter_id, entry in {0: [25, 99, ShutterEnums.Direction.STOP,  (70, ShutterEnums.State.STOPPED), False],
                                  1: [99, 99, ShutterEnums.Direction.STOP, (120, ShutterEnums.State.DOWN),      False],
                                  2: [50,   79,   ShutterEnums.Direction.STOP, (130, ShutterEnums.State.STOPPED)]}.items():
            validate(shutter_id, entry)

        controller._actual_positions[2] = 60  # Simulate position reporting
        master_controller._update_from_master_state({'module_nr': 0, 'status': 0b00010000})  # Third motor started again
        #                             +- actual position
        #                             |     +- desired position
        #                             |     |     +- direction                      +- state                      +- optional skip call check
        #                             v     v     v                                 v                             v
        for shutter_id, entry in {0: [25, 99, ShutterEnums.Direction.STOP,  (70, ShutterEnums.State.STOPPED), False],
                                  1: [99, 99, ShutterEnums.Direction.STOP, (120, ShutterEnums.State.DOWN),      False],
                                  2: [60,  79,    ShutterEnums.Direction.DOWN, (130, ShutterEnums.State.GOING_DOWN)]}.items():
            validate(shutter_id, entry)

        controller._actual_positions[2] = 79  # Simulate position reporting
        master_controller._update_from_master_state({'module_nr': 0, 'status': 0b00000000})  # Third motor stopped again
        #                             +- actual position
        #                             |     +- desired position
        #                             |     |     +- direction                       +- state                     +- optional skip call check
        #                             v     v     v                                  v                            v
        for shutter_id, entry in {0: [25, 99, ShutterEnums.Direction.STOP,  (70, ShutterEnums.State.STOPPED), False],
                                  1: [99, 99, ShutterEnums.Direction.STOP, (120, ShutterEnums.State.DOWN),      False],
                                  2: [79,   79,   ShutterEnums.Direction.STOP, (130, ShutterEnums.State.DOWN)]}.items():
            validate(shutter_id, entry)

        states = controller.get_states()
        states['status'].pop(3)  # Remove the "unused" shutter
        states['detail'].pop(3)
        self.assertDictEqual(states, {'detail': {0: {'actual_position': 25,
                                                     'desired_position': 99,
                                                     'state': 'stopped',
                                                     'last_change': 70},
                                                 1: {'actual_position': 99,
                                                     'desired_position': 99,
                                                     'state': 'down',
                                                     'last_change': 120},
                                                 2: {'actual_position': 79,
                                                     'desired_position': 79,
                                                     'state': 'down',
                                                     'last_change': 130}},
                                  'status': ['stopped', 'down', 'down']})