"""Module for XKXN Exceptions.""" from __future__ import annotations import logging from typing import Any class XKNXException(Exception): """Default XKNX Exception.""" def __eq__(self, other: object | None) -> bool: """Equal operator.""" return repr(self) == repr(other) def __hash__(self) -> int: """Hash function.""" return hash(str(self)) def __repr__(self) -> str: """Representation of object.""" return str(self) class CommunicationError(XKNXException): """Unable to communicate with KNX bus.""" def __init__(self, message: str, should_log: bool = True) -> None: """Instantiate exception.""" super().__init__(message) self.should_log = should_log class ConfirmationError(CommunicationError): """No confirmation received from KNX server for sent Telegram.""" class TunnellingAckError(CommunicationError): """No ACK or error status received from UDP KNX server for sent Telegram.""" class IPSecureError(CommunicationError): """Error in IP Secure communication.""" class CouldNotParseTelegram(XKNXException): """Could not parse telegram error.""" def __init__(self, description: str, **kwargs: Any) -> None: """Initialize CouldNotParseTelegram class.""" super().__init__() self.description = description self.parameter = kwargs def _format_parameter(self) -> str: return " ".join( [f"{key}={value!r}" for (key, value) in sorted(self.parameter.items())] ) def __str__(self) -> str: """Return object as readable string.""" return ( "' ) class CouldNotParseKNXIP(XKNXException): """Exception class for wrong KNXIP data.""" def __init__(self, description: str = "") -> None: """Initialize CouldNotParseKNXIP class.""" super().__init__() self.description = description def __str__(self) -> str: """Return object as readable string.""" return f'' class KNXSecureValidationError(CouldNotParseKNXIP): """Exception class for invalid KNX Secure data.""" def __str__(self) -> str: """Return object as readable string.""" return f'' class IncompleteKNXIPFrame(CouldNotParseKNXIP): """ Exception class for incomplete KNXIP data. Used for TCP connections to indicate to buffer the data until the complete frame is received. UDP connections should just handle CouldNotParseKNXIP. """ def __str__(self) -> str: """Return object as readable string.""" return f'' class CouldNotParseCEMI(XKNXException): """Exception class for wrong CEMI data.""" def __init__(self, description: str = "") -> None: """Initialize CouldNotParseCEMI class.""" super().__init__() self.description = description def __str__(self) -> str: """Return object as readable string.""" return f'' class UnsupportedCEMIMessage(XKNXException): """Exception class for unsupported CEMI Messages.""" def __init__(self, description: str = "") -> None: """Initialize UnsupportedCEMIMessage class.""" super().__init__() self.description = description def __str__(self) -> str: """Return object as readable string.""" return f'' class ConversionError(XKNXException): """Exception class for error while converting one type to another.""" def __init__(self, description: str, **kwargs: Any) -> None: """Initialize ConversionError class.""" super().__init__() self.description = description self.parameter = kwargs def _format_parameter(self) -> str: return " ".join( [f"{key}={value!r}" for (key, value) in sorted(self.parameter.items())] ) def __str__(self) -> str: """Return object as readable string.""" return f'' class CouldNotParseAddress(XKNXException): """Exception class for wrong address format.""" def __init__(self, address: Any = None, message: str = "") -> None: """Initialize CouldNotParseAddress class.""" super().__init__() self.address = address self.message = message def __str__(self) -> str: """Return object as readable string.""" _msg = f'message="{self.message}" ' if self.message else "" return f"" class DeviceIllegalValue(XKNXException): """Exception class for setting a value of a device with an illegal value.""" def __init__(self, description: str, value: Any) -> None: """Initialize DeviceIllegalValue class.""" super().__init__() self.value = value self.description = description def __str__(self) -> str: """Return object as readable string.""" return f'' class DataSecureError(XKNXException): """Exception class for KNX Data Secure handling.""" def __init__(self, message: str, log_level: int = logging.WARNING) -> None: """Instantiate exception.""" super().__init__(message) self.log_level = log_level class InvalidSecureConfiguration(XKNXException): """Exception class used when the secure configuration is invalid.""" class ManagementConnectionError(XKNXException): """Exception class used when a management connection fails.""" class ManagementConnectionRefused(ManagementConnectionError): """Exception class used when a management connection request is refused.""" class ManagementConnectionTimeout(ManagementConnectionError): """Exception class used when a management connection timed out."""