def test_address_mode_timeout(self):
        """ Test address mode timeout. """
        action = power_api.get_voltage(power_api.POWER_MODULE)
        sad = power_api.set_addressmode(power_api.POWER_MODULE)
        sad_p1c = power_api.set_addressmode(power_api.P1_CONCENTRATOR)

        serial_mock = RS485(
            SerialMock(
                [
                    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(''),  # 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)),
                    sin(action.create_input(1, 5)),
                    sout(action.create_output(1, 5, 49.5))
                ],
                1))

        comm = PowerCommunicatorTest._get_communicator(serial_mock,
                                                       address_mode_timeout=1)
        comm.start()

        comm.start_address_mode()
        time.sleep(1.1)

        self.assertEquals((49.5, ), comm.do_command(1, action))
    def test_address_mode(self):
        """ Test the address mode. """
        sad = power_api.set_addressmode(power_api.POWER_MODULE)
        sad_p1c = power_api.set_addressmode(power_api.P1_CONCENTRATOR)

        serial_mock = RS485(
            SerialMock(
                [
                    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(''),  # 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))
                ],
                1))
        SetUpTestInjections(power_db=PowerCommunicatorTest.FILE)

        controller = PowerController()
        comm = PowerCommunicatorTest._get_communicator(
            serial_mock, power_controller=controller)
        comm.start()

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

        comm.start_address_mode()
        self.assertTrue(comm.in_address_mode())
        time.sleep(0.5)
        comm.stop_address_mode()

        self.assertEqual(controller.get_free_address(), 4)
        self.assertFalse(comm.in_address_mode())
예제 #3
0
    def test_do_command_in_address_mode(self):
        """ Test the behavior of do_command in address mode."""
        action = power_api.get_voltage(power_api.POWER_API_8_PORTS)
        sad = power_api.set_addressmode()

        serial_mock = RS485(SerialMock(
            [sin(sad.create_input(power_api.BROADCAST_ADDRESS, 1, power_api.ADDRESS_MODE)),
             sout(''),  # Timeout read after 1 second
             sin(sad.create_input(power_api.BROADCAST_ADDRESS, 2, power_api.NORMAL_MODE)),
             sin(action.create_input(1, 3)),
             sout(action.create_output(1, 3, 49.5))],
            1
        ))

        comm = self.__get_communicator(serial_mock)
        comm.start()

        comm.start_address_mode()

        try:
            comm.do_command(1, action)
            self.assertFalse(True)
        except InAddressModeException:
            pass

        comm.stop_address_mode()

        self.assertEquals((49.5, ), comm.do_command(1, action))
예제 #4
0
    def __do_address_mode(self):
        """ This code is running in a thread when in address mode. """
        expire = time.time() + self.__address_mode_timeout
        address_mode = power_api.set_addressmode()
        want_an_address_8 = power_api.want_an_address(
            power_api.POWER_API_8_PORTS)
        want_an_address_12 = power_api.want_an_address(
            power_api.POWER_API_12_PORTS)
        set_address = power_api.set_address()

        # AGT start
        data = address_mode.create_input(power_api.BROADCAST_ADDRESS,
                                         self.__get_cid(),
                                         power_api.ADDRESS_MODE)
        self.__write_to_serial(data)

        # Wait for WAA and answer.
        while not self.__address_mode_stop and time.time() < expire:
            try:
                header, data = self.__read_from_serial()

                waa_8 = want_an_address_8.check_header_partial(header)
                waa_12 = want_an_address_12.check_header_partial(header)

                if not waa_8 and not waa_12:
                    LOGGER.warning(
                        "Received non WAA/WAD message in address mode")
                else:
                    (old_address, cid) = (ord(header[:2][1]), header[2:3])
                    # Ask power_controller for new address, and register it.
                    new_address = self.__power_controller.get_free_address()

                    if self.__power_controller.module_exists(old_address):
                        self.__power_controller.readdress_power_module(
                            old_address, new_address)
                    else:
                        version = power_api.POWER_API_8_PORTS if waa_8 else power_api.POWER_API_12_PORTS

                        self.__power_controller.register_power_module(
                            new_address, version)

                    # Send new address to power module
                    address_data = set_address.create_input(
                        old_address, ord(cid), new_address)
                    self.__write_to_serial(address_data)

            except CommunicationTimedOutException:
                pass  # Didn't receive a command, no problem.
            except Exception as exception:
                traceback.print_exc()
                LOGGER.warning("Got exception in address mode: %s", exception)

        # AGT stop
        data = address_mode.create_input(power_api.BROADCAST_ADDRESS,
                                         self.__get_cid(),
                                         power_api.NORMAL_MODE)
        self.__write_to_serial(data)

        self.__address_mode = False
        self.__address_thread = None
    def test_do_command_in_address_mode(self):
        """ Test the behavior of do_command in address mode."""
        action = power_api.get_voltage(power_api.POWER_API_8_PORTS)
        sad = power_api.set_addressmode()

        serial_mock = RS485(SerialMock(
            [sin(sad.create_input(power_api.BROADCAST_ADDRESS, 1, power_api.ADDRESS_MODE)),
             sout(''), ## Timeout read after 1 second
             sin(sad.create_input(power_api.BROADCAST_ADDRESS, 2, power_api.NORMAL_MODE)),
             sin(action.create_input(1, 3)),
             sout(action.create_output(1, 3, 49.5))
            ], 1))

        comm = self.__get_communicator(serial_mock)
        comm.start()

        comm.start_address_mode()

        try:
            comm.do_command(1, action)
            self.assertFalse(True)
        except InAddressModeException:
            pass

        comm.stop_address_mode()

        self.assertEquals((49.5, ), comm.do_command(1, action))
    def test_address_mode(self):
        """ Test the address mode. """
        sad = power_api.set_addressmode()
        serial_mock = RS485(SerialMock(
            [sin(sad.create_input(power_api.BROADCAST_ADDRESS, 1, power_api.ADDRESS_MODE)),
             sout(power_api.want_an_address(power_api.POWER_API_8_PORTS).create_output(0, 0)),
             sin(power_api.set_address().create_input(0, 0, 1)),
             sout(power_api.want_an_address(power_api.POWER_API_12_PORTS).create_output(0, 0)),
             sin(power_api.set_address().create_input(0, 0, 2)),
             sout(''), ## Timeout read after 1 second
             sin(sad.create_input(power_api.BROADCAST_ADDRESS, 2, power_api.NORMAL_MODE))
            ], 1))

        controller = PowerController(PowerCommunicatorTest.FILE)
        comm = self.__get_communicator(serial_mock, power_controller=controller)
        comm.start()

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

        comm.start_address_mode()
        self.assertTrue(comm.in_address_mode())
        time.sleep(0.5)
        comm.stop_address_mode()

        self.assertEqual(controller.get_free_address(), 3)
        self.assertFalse(comm.in_address_mode())
예제 #7
0
    def test_address_mode(self):
        """ Test the address mode. """
        sad = power_api.set_addressmode()
        serial_mock = RS485(SerialMock(
            [sin(sad.create_input(power_api.BROADCAST_ADDRESS, 1, power_api.ADDRESS_MODE)),
             sout(power_api.want_an_address(power_api.POWER_API_8_PORTS).create_output(0, 0)),
             sin(power_api.set_address().create_input(0, 0, 1)),
             sout(power_api.want_an_address(power_api.POWER_API_12_PORTS).create_output(0, 0)),
             sin(power_api.set_address().create_input(0, 0, 2)),
             sout(''), ## Timeout read after 1 second
             sin(sad.create_input(power_api.BROADCAST_ADDRESS, 2, power_api.NORMAL_MODE))
            ], 1))

        controller = PowerController(PowerCommunicatorTest.FILE)
        comm = self.__get_communicator(serial_mock, power_controller=controller)
        comm.start()

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

        comm.start_address_mode()
        self.assertTrue(comm.in_address_mode())
        time.sleep(0.5)
        comm.stop_address_mode()

        self.assertEqual(controller.get_free_address(), 3)
        self.assertFalse(comm.in_address_mode())
예제 #8
0
 def test_set_addressmode_p1(self):
     action = power_api.set_addressmode(power_api.P1_CONCENTRATOR)
     assert decode(
         action.create_input(
             power_api.BROADCAST_ADDRESS, 2,
             power_api.ADDRESS_MODE)) == 'STRC\xff\x02SAGT\x01\x01\xc5\r\n'
     assert decode(action.create_output(
         1, 1)) == 'RTRC\x01\x01SAGT\x00\x00\r\n'
예제 #9
0
 def test_set_addressmode(self):
     action = power_api.set_addressmode(power_api.POWER_MODULE)
     assert decode(
         action.create_input(
             power_api.BROADCAST_ADDRESS, 1,
             power_api.ADDRESS_MODE)) == 'STRE\xff\x01SAGT\x01\x01\x0b\r\n'
     assert decode(action.create_output(1,
                                        1)) == 'RTRE\x01\x01SAGT\x00t\r\n'
예제 #10
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())
예제 #11
0
    def __do_address_mode(self):
        """ This code is running in a thread when in address mode. """
        expire = time.time() + self.__address_mode_timeout
        address_mode = power_api.set_addressmode()
        want_an_address_8 = power_api.want_an_address(power_api.POWER_API_8_PORTS)
        want_an_address_12 = power_api.want_an_address(power_api.POWER_API_12_PORTS)
        set_address = power_api.set_address()

        # AGT start
        data = address_mode.create_input(power_api.BROADCAST_ADDRESS,
                                         self.__get_cid(),
                                         power_api.ADDRESS_MODE)
        self.__write_to_serial(data)

        # Wait for WAA and answer.
        while not self.__address_mode_stop and time.time() < expire:
            try:
                header, data = self.__read_from_serial()

                waa_8 = want_an_address_8.check_header_partial(header)
                waa_12 = want_an_address_12.check_header_partial(header)

                if not waa_8 and not waa_12:
                    LOGGER.warning("Received non WAA/WAD message in address mode")
                else:
                    (old_address, cid) = (ord(header[:2][1]), header[2:3])
                    # Ask power_controller for new address, and register it.
                    new_address = self.__power_controller.get_free_address()

                    if self.__power_controller.module_exists(old_address):
                        self.__power_controller.readdress_power_module(old_address, new_address)
                    else:
                        version = power_api.POWER_API_8_PORTS if waa_8 else power_api.POWER_API_12_PORTS

                        self.__power_controller.register_power_module(new_address, version)

                    # Send new address to power module
                    address_data = set_address.create_input(old_address, ord(cid), new_address)
                    self.__write_to_serial(address_data)

            except CommunicationTimedOutException:
                pass  # Didn't receive a command, no problem.
            except Exception as exception:
                traceback.print_exc()
                LOGGER.warning("Got exception in address mode: %s", exception)

        # AGT stop
        data = address_mode.create_input(power_api.BROADCAST_ADDRESS,
                                         self.__get_cid(),
                                         power_api.NORMAL_MODE)
        self.__write_to_serial(data)

        self.__address_mode = False
        self.__address_thread = None
    def test_do_command_in_address_mode(self):
        """ Test the behavior of do_command in address mode."""
        action = power_api.get_voltage(power_api.POWER_MODULE)
        sad = power_api.set_addressmode(power_api.POWER_MODULE)
        sad_p1c = power_api.set_addressmode(power_api.P1_CONCENTRATOR)

        serial_mock = RS485(
            SerialMock(
                [
                    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(''),  # 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)),
                    sin(action.create_input(1, 5)),
                    sout(action.create_output(1, 5, 49.5))
                ],
                1))

        comm = PowerCommunicatorTest._get_communicator(serial_mock)
        comm.start()

        comm.start_address_mode()

        with self.assertRaises(InAddressModeException):
            comm.do_command(1, action)

        comm.stop_address_mode()

        self.assertEquals((49.5, ), comm.do_command(1, action))
예제 #13
0
    def test_address_mode_timeout(self):
        """ Test address mode timeout. """
        action = power_api.get_voltage(power_api.POWER_MODULE)
        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(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)),
            sin(action.create_input(1, 5)),
            sout(action.create_output(1, 5, 49.5))
        ])
        self.communicator = PowerCommunicator(address_mode_timeout=1)
        self.serial.start()
        self.communicator.start()

        self.communicator.start_address_mode()
        time.sleep(1.1)

        self.assertEqual((49.5, ), self.communicator.do_command(1, action))
예제 #14
0
    def test_do_command_in_address_mode(self):
        """ Test the behavior of do_command in address mode."""
        action = power_api.get_voltage(power_api.POWER_MODULE)
        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(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)),
            sin(action.create_input(1, 5)),
            sout(action.create_output(1, 5, 49.5))
        ])
        self.serial.start()
        self.communicator.start()

        self.communicator.start_address_mode()
        with self.assertRaises(InAddressModeException):
            self.communicator.do_command(1, action)

        self.communicator.stop_address_mode()
        self.assertEqual((49.5, ), self.communicator.do_command(1, action))
예제 #15
0
    def test_address_mode_timeout(self):
        """ Test address mode timeout. """
        action = power_api.get_voltage(power_api.POWER_API_8_PORTS)
        sad = power_api.set_addressmode()

        serial_mock = RS485(SerialMock(
            [sin(sad.create_input(power_api.BROADCAST_ADDRESS, 1, power_api.ADDRESS_MODE)),
             sout(''), ## Timeout read after 1 second
             sin(sad.create_input(power_api.BROADCAST_ADDRESS, 2, power_api.NORMAL_MODE)),
             sin(action.create_input(1, 3)),
             sout(action.create_output(1, 3, 49.5))
            ], 1))

        comm = self.__get_communicator(serial_mock, address_mode_timeout=1)
        comm.start()

        comm.start_address_mode()
        time.sleep(1.1)

        self.assertEquals((49.5, ), comm.do_command(1, action))
예제 #16
0
    def __do_address_mode(self):
        # type: () -> None
        """ This code is running in a thread when in address mode. """
        if self.__power_store is None:
            self.__address_mode = False
            self.__address_thread = None
            return

        expire = time.time() + self.__address_mode_timeout
        address_mode = power_api.set_addressmode(power_api.ENERGY_MODULE)
        address_mode_p1c = power_api.set_addressmode(power_api.P1_CONCENTRATOR)
        want_an_address_8 = power_api.want_an_address(power_api.POWER_MODULE)
        want_an_address_12 = power_api.want_an_address(power_api.ENERGY_MODULE)
        want_an_address_p1c = power_api.want_an_address(
            power_api.P1_CONCENTRATOR)
        set_address = power_api.set_address(power_api.ENERGY_MODULE)
        set_address_p1c = power_api.set_address(power_api.P1_CONCENTRATOR)

        # AGT start
        data = address_mode.create_input(power_api.BROADCAST_ADDRESS,
                                         self.__get_cid(),
                                         power_api.ADDRESS_MODE)
        self.__write_to_serial(data)
        data = address_mode_p1c.create_input(power_api.BROADCAST_ADDRESS,
                                             self.__get_cid(),
                                             power_api.ADDRESS_MODE)
        self.__write_to_serial(data)

        # Wait for WAA and answer.
        while not self.__address_mode_stop and time.time() < expire:
            try:
                header, data = self.__read_from_serial()

                if set_address.check_header_partial(
                        header) or set_address_p1c.check_header_partial(
                            header):
                    continue

                version = None
                if want_an_address_8.check_header_partial(header):
                    version = power_api.POWER_MODULE
                elif want_an_address_12.check_header_partial(header):
                    version = power_api.ENERGY_MODULE
                elif want_an_address_p1c.check_header_partial(header):
                    version = power_api.P1_CONCENTRATOR

                if version is None:
                    logger.warning(
                        "Received unexpected message in address mode")
                else:
                    (old_address, cid) = (header[:2][1], header[2:3])
                    # Ask power_controller for new address, and register it.
                    new_address = self.__power_store.get_free_address()

                    if self.__power_store.module_exists(old_address):
                        self.__power_store.readdress_power_module(
                            old_address, new_address)
                    else:
                        self.__power_store.register_power_module(
                            new_address, version)

                    # Send new address to module
                    if version == power_api.P1_CONCENTRATOR:
                        address_data = set_address_p1c.create_input(
                            old_address, ord(cid), new_address)
                    else:
                        # Both power- and energy module share the same API
                        address_data = set_address.create_input(
                            old_address, ord(cid), new_address)
                    self.__write_to_serial(address_data)

            except CommunicationTimedOutException:
                pass  # Didn't receive a command, no problem.
            except Exception as exception:
                logger.exception("Got exception in address mode: %s",
                                 exception)

        # AGT stop
        data = address_mode.create_input(power_api.BROADCAST_ADDRESS,
                                         self.__get_cid(),
                                         power_api.NORMAL_MODE)
        self.__write_to_serial(data)
        data = address_mode_p1c.create_input(power_api.BROADCAST_ADDRESS,
                                             self.__get_cid(),
                                             power_api.NORMAL_MODE)
        self.__write_to_serial(data)

        self.__address_mode = False