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())
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 __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())
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'
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'
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 __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))
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))
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))
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))
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