diff --git a/laborious/utils/repository/opc_repository.py b/laborious/utils/repository/opc_repository.py index 6742194..1315c44 100644 --- a/laborious/utils/repository/opc_repository.py +++ b/laborious/utils/repository/opc_repository.py @@ -158,7 +158,7 @@ class OpcRepository(): f"Failed to disconnect from OPC server: {e}", self.metadata) self.client = None - def __del__(self): + def shutdown(self): """ Disconnects from the OPC server when the object is destroyed. """ @@ -170,7 +170,8 @@ class OpcRepository(): async def validate_connection(self) -> tuple[bool, dict[str, Any]]: """ - Validates the connection to the OPC server. + Validates the connection to the OPC server using protocol state checking. + If the connection is not established, it attempts to reconnect. If the connection is established but the client is not connected, it attempts to reconnect. @@ -198,28 +199,36 @@ class OpcRepository(): # Check if client is connected using asyncua's connection state try: - # Try to get a simple node to test connection - await self.client.get_node("ns=0;i=2253") # Server node - except Exception: - self.logger.custom_error( - f"OPC server {self.id} is not connected", self.metadata) - - if self.last_reconnection_time is None or (datetime.now() - self.last_reconnection_time).total_seconds( - ) > self.reconnection_interval: - await self.disconnect() - self.logger.custom_info( - f"Trying to reconnect to OPC server {self.id}...", self.metadata) - return await self.connect() + if self.client.uaclient.protocol is None or self.client.uaclient.protocol.state == "closed": + # OPC server is not connected + self.logger.custom_error( + f"OPC server {self.id} is not connected", self.metadata) + if self.last_reconnection_time is None or (datetime.now() - self.last_reconnection_time).total_seconds( + ) > self.reconnection_interval: + await self.disconnect() + self.logger.custom_info( + f"Trying to reconnect to OPC server {self.id}...", self.metadata) + return await self.connect() + return False, { + "notification_id": f"OPC_CONNECTION_AWAITING_RECONNECTION_WINDOW_{self.id}", + "message": f"OPC server {self.id} is not connected, waiting for next reconnection window...", + "block": "opc_repository", + "level": NotificationLevel.WARNING + } + return True, {} + except Exception as e: + trace = traceback.format_exc() + message = f"Failed to validate connection to OPC server: {e}" + self.logger.custom_error(message, self.metadata) return False, { - "notification_id": f"OPC_CONNECTION_AWAITING_RECONNECTION_WINDOW_{self.id}", - "message": f"OPC server {self.id} is not connected, waiting for next reconnection window...", + "notification_id": f"OPC_CONNECTION_CHECK_ERROR_{self.id}", + "message": message, "block": "opc_repository", - "level": NotificationLevel.WARNING + "level": NotificationLevel.ERROR, + "attachment_content": trace } - return True, {} - async def write_data(self, node: str, value: Any, data_type: str, logger: Logger, metadata: dict[str, Any]) -> tuple[bool, dict[str, Any]]: """ diff --git a/values.yaml b/values.yaml index 0b5632e..76ca717 100644 --- a/values.yaml +++ b/values.yaml @@ -11,7 +11,7 @@ image: # This sets the pull policy for images. pullPolicy: Always # Overrides the image tag whose default is the chart appVersion. - tag: "0.4.5" + tag: "0.4.4" # This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ imagePullSecrets: