def test_equal(self): """Test if the equal operator works in all cases.""" assert IndividualAddress("1.0.0") == IndividualAddress(4096) assert IndividualAddress("1.0.0") != IndividualAddress("1.1.1") assert IndividualAddress("1.0.0") is not None assert IndividualAddress("1.0.0") != "example" assert IndividualAddress("1.1.1") != GroupAddress("1/1/1") assert IndividualAddress(250) != GroupAddress(250) assert IndividualAddress(250) != 250
async def nm_individual_address_check( xknx: XKNX, individual_address: IndividualAddressableType) -> bool: """Check if the individual address is occupied on the network.""" try: async with xknx.management.connection( address=IndividualAddress(individual_address)) as connection: try: response = await connection.request( payload=apci.DeviceDescriptorRead(descriptor=0), expected=apci.DeviceDescriptorResponse, ) except ManagementConnectionTimeout as ex: # if nothing is received (-> timeout) IA is free logger.debug("No device answered to connection attempt. %s", ex) return False if isinstance(response.payload, apci.DeviceDescriptorResponse): # if response is received IA is occupied logger.debug("Device found at %s", individual_address) return True return False except ManagementConnectionRefused as ex: # if Disconnect is received immediately, IA is occupied logger.debug("Device does not support transport layer connections. %s", ex) return True
def test_equal(self): """Test if the equal operator works in all cases.""" assert GroupAddress("1/0") == GroupAddress(2048) assert GroupAddress("1/1") != GroupAddress("1/1/0") assert GroupAddress("1/0") is not None assert GroupAddress("1/0") != "example" assert GroupAddress(1) != IndividualAddress(1) assert GroupAddress(1) != 1
def __init__( self, address: IndividualAddress | None = None, ) -> None: """Initialize a new instance of IndividualAddressWrite.""" if address is None: address = IndividualAddress("0.0.0") self.address = address
def test_equal(self): """Test if the equal operator works in all cases.""" assert InternalGroupAddress("i 123") == InternalGroupAddress("i 123") assert InternalGroupAddress("i-asdf") == InternalGroupAddress("i asdf") assert InternalGroupAddress("i-asdf") == InternalGroupAddress("Iasdf") assert InternalGroupAddress("i-1") != InternalGroupAddress("i-2") assert InternalGroupAddress("i-1") is not None assert InternalGroupAddress("i-example") != "example" assert InternalGroupAddress("i-0") != GroupAddress(0) assert InternalGroupAddress("i-1") != IndividualAddress(1) assert InternalGroupAddress("i-1") != 1
async def _receive_telegram(self, group_address: str, payload: APCI) -> None: """Inject incoming KNX telegram.""" self.xknx.telegrams.put_nowait( Telegram( destination_address=GroupAddress(group_address), direction=TelegramDirection.INCOMING, payload=payload, source_address=IndividualAddress(self.INDIVIDUAL_ADDRESS), ) ) await self.hass.async_block_till_done()
def __init__( self, serial: bytes | None = None, address: IndividualAddress | None = None, ) -> None: """Initialize a new instance of IndividualAddressSerialWrite.""" if serial is None: serial = bytes([0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) if address is None: address = IndividualAddress("0.0.0") self.serial = serial self.address = address
def __init__( self, serial: Optional[bytes] = None, address: Optional[IndividualAddress] = None, ) -> None: """Initialize a new instance of IndividualAddressSerialResponse.""" if serial is None: serial = bytes([0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) if address is None: address = IndividualAddress("0.0.0") self.serial = serial self.address = address
class IndividualAddressSerialWrite(APCI): """IndividualAddressSerialWrite service.""" CODE = APCIExtendedService.INDIVIDUAL_ADDRESS_SERIAL_WRITE def __init__( self, serial: bytes | None = None, address: IndividualAddress | None = None, ) -> None: """Initialize a new instance of IndividualAddressSerialWrite.""" if serial is None: serial = bytes([0x00, 0x00, 0x00, 0x00, 0x00, 0x00]) if address is None: address = IndividualAddress("0.0.0") self.serial = serial self.address = address def calculated_length(self) -> int: """Get length of APCI payload.""" return 13 def from_knx(self, raw: bytes) -> None: """Parse/deserialize from KNX/IP raw data.""" self.serial, address_high, address_low, _ = struct.unpack( "!6sBBI", raw[2:]) self.address = IndividualAddress((address_high, address_low)) def to_knx(self) -> bytes: """Serialize to KNX/IP raw data.""" if len(self.serial) != 6: raise ConversionError("Serial must be 6 bytes.") address_high, address_low = self.address.to_knx() payload = struct.pack("!6sBBI", self.serial, address_high, address_low, 0) return encode_cmd_and_payload(self.CODE, appended_payload=payload) def __str__(self) -> str: """Return object as readable string.""" return f'<IndividualAddressSerialWrite serial="{self.serial.hex()}" address="{self.address}" />'
class IndividualAddressWrite(APCI): """ IndividualAddressWrite service. Payload contains the serial number and (new) address of the device. """ CODE = APCIService.INDIVIDUAL_ADDRESS_WRITE def __init__( self, address: IndividualAddress | None = None, ) -> None: """Initialize a new instance of IndividualAddressWrite.""" if address is None: address = IndividualAddress("0.0.0") self.address = address def calculated_length(self) -> int: """Get length of APCI payload.""" return 3 def from_knx(self, raw: bytes) -> None: """Parse/deserialize from KNX/IP raw data.""" address_high, address_low = struct.unpack("!BB", raw[2:]) self.address = IndividualAddress((address_high, address_low)) def to_knx(self) -> bytes: """Serialize to KNX/IP raw data.""" return encode_cmd_and_payload(self.CODE, appended_payload=bytes( self.address.to_knx())) def __str__(self) -> str: """Return object as readable string.""" return f'<IndividualAddressWrite address="{self.address}" />'
def test_with_valid(self, address_test, address_raw): """Test with some valid addresses.""" assert IndividualAddress(address_test).raw == address_raw
def test_to_knx(self): """Test if `IndividualAddress.to_knx()` generates valid byte tuples.""" assert IndividualAddress("0.0.0").to_knx() == (0x0, 0x0) assert IndividualAddress("15.15.255").to_knx() == (0xFF, 0xFF)
def test_is_device(self): """Test if `IndividualAddress.is_device` works like excepted.""" assert IndividualAddress("1.0.1").is_device assert not IndividualAddress("1.0.0").is_device
def test_with_none(self): """Test initialization with None object.""" assert IndividualAddress(None).raw == 0
def test_with_bytes(self): """Test initialization with Bytes.""" assert IndividualAddress((0x12, 0x34)).raw == 0x1234
def test_with_int(self): """Test initialization with free format address as integer.""" assert IndividualAddress(49552).raw == 49552
def test_with_invalid(self, address_test): """Test with some invalid addresses.""" with pytest.raises(CouldNotParseAddress): IndividualAddress(address_test)
def from_knx(self, raw: bytes) -> None: """Parse/deserialize from KNX/IP raw data.""" address_high, address_low = struct.unpack("!BB", raw[2:]) self.address = IndividualAddress((address_high, address_low))
def test_representation(self): """Test string representation of address.""" assert repr(IndividualAddress("2.3.4")) == 'IndividualAddress("2.3.4")'
(0xFF, 0xFF): 65535, GroupAddress("1/1/111"): 2415, None: 0, } group_addresses_invalid = [ "0/2049", "0/8/0", "0/0/256", "32/0", "0/0a", "a0/0", "abc", "1.1.1", "0.0", IndividualAddress("11.11.111"), 65536, (0xFF, 0xFFF), (0xFFF, 0xFF), (-1, -1), [], ] individual_addresses_valid = { "0.0.0": 0, "123": 123, "1.0.0": 4096, "1.1.0": 4352, "1.1.1": 4353, "1.1.11": 4363, "1.1.111": 4463,