SIENTIAPDE-1646
Refactor OPC and OpcRepository classes to remove logger dependency and streamline logging calls - Removed logger attribute from OPC and OpcRepository classes, replacing direct logger calls with class methods for logging. - Updated write_data method signatures to eliminate logger parameter, simplifying the interface. - Adjusted related tests to reflect changes in method signatures and logging behavior.
This commit is contained in:
@@ -32,7 +32,6 @@ class OPC(SientiaMonitoring):
|
|||||||
Attributes:
|
Attributes:
|
||||||
opc_servers (dict): Configuration for multiple OPC servers
|
opc_servers (dict): Configuration for multiple OPC servers
|
||||||
opc_repository (dict): Active OPC repository connections
|
opc_repository (dict): Active OPC repository connections
|
||||||
logger (Logger): Logging and observability instance
|
|
||||||
notification_handler (NotificationHandler): Notification management instance
|
notification_handler (NotificationHandler): Notification management instance
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -43,8 +42,6 @@ class OPC(SientiaMonitoring):
|
|||||||
notification_handler: NotificationHandler,
|
notification_handler: NotificationHandler,
|
||||||
metrics_controller: MetricsController,
|
metrics_controller: MetricsController,
|
||||||
):
|
):
|
||||||
self.logger = logger
|
|
||||||
self.notification_handler = notification_handler
|
|
||||||
self.opc_servers = opc_servers
|
self.opc_servers = opc_servers
|
||||||
|
|
||||||
SientiaMonitoring.__init__(self, logger, notification_handler, metrics_controller)
|
SientiaMonitoring.__init__(self, logger, notification_handler, metrics_controller)
|
||||||
@@ -61,7 +58,7 @@ class OPC(SientiaMonitoring):
|
|||||||
are reported through the notification system.
|
are reported through the notification system.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.logger.info('Initializing OPC servers...')
|
self.info('Initializing OPC servers...')
|
||||||
for opc_id, server in self.opc_servers.items():
|
for opc_id, server in self.opc_servers.items():
|
||||||
self.opc_repository[opc_id] = OpcRepository(
|
self.opc_repository[opc_id] = OpcRepository(
|
||||||
opc_id=opc_id,
|
opc_id=opc_id,
|
||||||
@@ -91,8 +88,9 @@ class OPC(SientiaMonitoring):
|
|||||||
attachment_content=err.get('attachment_content', traceback.format_exc()),
|
attachment_content=err.get('attachment_content', traceback.format_exc()),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.logger.info(
|
self.info(
|
||||||
f'OPC server {opc_id}:{server["server_name"]} connected successfully.'
|
f'OPC server {opc_id}:{server["server_name"]} connected successfully.',
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
|
|
||||||
def write_data(
|
def write_data(
|
||||||
@@ -120,7 +118,7 @@ class OPC(SientiaMonitoring):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
is_success, info_data = self.opc_repository[server_id].write_data(
|
is_success, info_data = self.opc_repository[server_id].write_data(
|
||||||
tag, data, data_type, self.logger, metadata
|
tag, data, data_type, metadata
|
||||||
)
|
)
|
||||||
if not is_success:
|
if not is_success:
|
||||||
self.send_notification(
|
self.send_notification(
|
||||||
|
|||||||
@@ -80,12 +80,10 @@ class OpcRepository(SientiaMonitoring):
|
|||||||
self.cert_path = cert_path
|
self.cert_path = cert_path
|
||||||
self.private_key_path = private_key_path
|
self.private_key_path = private_key_path
|
||||||
self.server_cert_path = server_cert_path
|
self.server_cert_path = server_cert_path
|
||||||
self.logger = logger
|
|
||||||
self.error_count = 0
|
self.error_count = 0
|
||||||
self.reconnection_interval = reconnection_interval
|
self.reconnection_interval = reconnection_interval
|
||||||
self.last_reconnection_time: datetime | None = None
|
self.last_reconnection_time: datetime | None = None
|
||||||
self.disconnection_interval = 10.0
|
self.disconnection_interval = 10.0
|
||||||
self.notification_handler = notification_handler
|
|
||||||
self.client: Client | None = None
|
self.client: Client | None = None
|
||||||
|
|
||||||
SientiaMonitoring.__init__(self, logger, notification_handler, metrics_controller)
|
SientiaMonitoring.__init__(self, logger, notification_handler, metrics_controller)
|
||||||
@@ -118,7 +116,7 @@ class OpcRepository(SientiaMonitoring):
|
|||||||
raise ValueError('Client must be initialized before setting security')
|
raise ValueError('Client must be initialized before setting security')
|
||||||
|
|
||||||
self.client.application_uri = self.server_uri or self.client.application_uri
|
self.client.application_uri = self.server_uri or self.client.application_uri
|
||||||
self.logger.custom_info('Setting security...', self.metadata)
|
self.info('Setting security...', self.metadata)
|
||||||
self.client.set_security(
|
self.client.set_security(
|
||||||
security_policies.SecurityPolicyBasic256,
|
security_policies.SecurityPolicyBasic256,
|
||||||
str(cert),
|
str(cert),
|
||||||
@@ -147,7 +145,7 @@ class OpcRepository(SientiaMonitoring):
|
|||||||
|
|
||||||
if self.cert_path:
|
if self.cert_path:
|
||||||
self.set_security()
|
self.set_security()
|
||||||
self.logger.custom_info(
|
self.info(
|
||||||
f'Starting connection to OPC server {self.id}:{self.server_name}...', self.metadata
|
f'Starting connection to OPC server {self.id}:{self.server_name}...', self.metadata
|
||||||
)
|
)
|
||||||
return self.try_connect()
|
return self.try_connect()
|
||||||
@@ -191,7 +189,7 @@ class OpcRepository(SientiaMonitoring):
|
|||||||
self.disconnect()
|
self.disconnect()
|
||||||
|
|
||||||
trace = traceback.format_exc()
|
trace = traceback.format_exc()
|
||||||
self.logger.custom_error(trace, self.metadata)
|
self.error(trace, self.metadata)
|
||||||
|
|
||||||
self.emit_metric_sync(metrics.OPC_CONNECTIONS_FAILED, tags)
|
self.emit_metric_sync(metrics.OPC_CONNECTIONS_FAILED, tags)
|
||||||
|
|
||||||
@@ -215,13 +213,13 @@ class OpcRepository(SientiaMonitoring):
|
|||||||
error_stack = []
|
error_stack = []
|
||||||
for i in range(5):
|
for i in range(5):
|
||||||
try:
|
try:
|
||||||
self.logger.custom_info(
|
self.info(
|
||||||
f'Disconnecting from OPC UA server, attempt {i + 1} of 5', self.metadata
|
f'Disconnecting from OPC UA server, attempt {i + 1} of 5', self.metadata
|
||||||
)
|
)
|
||||||
self.client.disconnect()
|
self.client.disconnect()
|
||||||
return []
|
return []
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.custom_error(
|
self.error(
|
||||||
f'Failed to disconnect from OPC UA server in attempt {i + 1} of 5: {e}',
|
f'Failed to disconnect from OPC UA server in attempt {i + 1} of 5: {e}',
|
||||||
self.metadata,
|
self.metadata,
|
||||||
)
|
)
|
||||||
@@ -254,7 +252,7 @@ class OpcRepository(SientiaMonitoring):
|
|||||||
attachment_content=json.dumps(errors, indent=4),
|
attachment_content=json.dumps(errors, indent=4),
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.logger.custom_warning(
|
self.warning(
|
||||||
f'Disconnected from OPC server {self.id} successfully', self.metadata
|
f'Disconnected from OPC server {self.id} successfully', self.metadata
|
||||||
)
|
)
|
||||||
self.emit_metric_sync(
|
self.emit_metric_sync(
|
||||||
@@ -299,14 +297,14 @@ class OpcRepository(SientiaMonitoring):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
if not self._session_alive():
|
if not self._session_alive():
|
||||||
self.logger.custom_error(f'OPC server {self.id} is not connected', self.metadata)
|
self.error(f'OPC server {self.id} is not connected', self.metadata)
|
||||||
if (
|
if (
|
||||||
self.last_reconnection_time is None
|
self.last_reconnection_time is None
|
||||||
or (datetime.now() - self.last_reconnection_time).total_seconds()
|
or (datetime.now() - self.last_reconnection_time).total_seconds()
|
||||||
> self.reconnection_interval
|
> self.reconnection_interval
|
||||||
):
|
):
|
||||||
self.disconnect()
|
self.disconnect()
|
||||||
self.logger.custom_info(
|
self.info(
|
||||||
f'Trying to reconnect to OPC server {self.id}...', self.metadata
|
f'Trying to reconnect to OPC server {self.id}...', self.metadata
|
||||||
)
|
)
|
||||||
return self.connect()
|
return self.connect()
|
||||||
@@ -323,7 +321,7 @@ class OpcRepository(SientiaMonitoring):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
trace = traceback.format_exc()
|
trace = traceback.format_exc()
|
||||||
message = f'Failed to validate connection to OPC server: {e}'
|
message = f'Failed to validate connection to OPC server: {e}'
|
||||||
self.logger.custom_error(message, self.metadata)
|
self.error(message, self.metadata)
|
||||||
return False, {
|
return False, {
|
||||||
'notification_id': f'OPC_CONNECTION_CHECK_ERROR_{self.id}',
|
'notification_id': f'OPC_CONNECTION_CHECK_ERROR_{self.id}',
|
||||||
'message': message,
|
'message': message,
|
||||||
@@ -333,7 +331,7 @@ class OpcRepository(SientiaMonitoring):
|
|||||||
}
|
}
|
||||||
|
|
||||||
def write_data(
|
def write_data(
|
||||||
self, node: str, value: Any, data_type: str, logger: Logger, metadata: dict[str, Any]
|
self, node: str, value: Any, data_type: str, metadata: dict[str, Any]
|
||||||
) -> tuple[bool, dict[str, Any]]:
|
) -> tuple[bool, dict[str, Any]]:
|
||||||
"""
|
"""
|
||||||
Write a typed value to an OPC UA node after validating connectivity.
|
Write a typed value to an OPC UA node after validating connectivity.
|
||||||
@@ -342,7 +340,6 @@ class OpcRepository(SientiaMonitoring):
|
|||||||
node: Node id string accepted by ``Client.get_node``.
|
node: Node id string accepted by ``Client.get_node``.
|
||||||
value: Scalar value to encode.
|
value: Scalar value to encode.
|
||||||
data_type: Key into ``data_type_map`` (e.g. float, str).
|
data_type: Key into ``data_type_map`` (e.g. float, str).
|
||||||
logger: Caller logger for per-write traces.
|
|
||||||
metadata: Workflow metadata for error context.
|
metadata: Workflow metadata for error context.
|
||||||
|
|
||||||
Return:
|
Return:
|
||||||
@@ -361,7 +358,7 @@ class OpcRepository(SientiaMonitoring):
|
|||||||
node_obj = self.client.get_node(node)
|
node_obj = self.client.get_node(node)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
trace = traceback.format_exc()
|
trace = traceback.format_exc()
|
||||||
logger.custom_error(trace, metadata.get('schedule_name', 'N/A'))
|
self.error(trace, metadata)
|
||||||
self.error_count += 1
|
self.error_count += 1
|
||||||
return False, {
|
return False, {
|
||||||
'notification_id': f'OPC_WRITE_GET_NODE_ERROR_{self.id}',
|
'notification_id': f'OPC_WRITE_GET_NODE_ERROR_{self.id}',
|
||||||
@@ -380,7 +377,7 @@ class OpcRepository(SientiaMonitoring):
|
|||||||
}
|
}
|
||||||
|
|
||||||
data = data_type_map[data_type]['converter'](value)
|
data = data_type_map[data_type]['converter'](value)
|
||||||
logger.custom_info(f'Writing {data} - {type(data)} to {node}', metadata)
|
self.info(f'Writing {data} - {type(data)} to {node}', metadata)
|
||||||
variant_type = data_type_map[data_type]['opc_type']
|
variant_type = data_type_map[data_type]['opc_type']
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -391,7 +388,7 @@ class OpcRepository(SientiaMonitoring):
|
|||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
trace = traceback.format_exc()
|
trace = traceback.format_exc()
|
||||||
logger.custom_error(trace, metadata)
|
self.error(trace, metadata)
|
||||||
self.error_count += 1
|
self.error_count += 1
|
||||||
return False, {
|
return False, {
|
||||||
'notification_id': f'OPC_WRITE_DATA_ERROR_{self.id}',
|
'notification_id': f'OPC_WRITE_DATA_ERROR_{self.id}',
|
||||||
|
|||||||
@@ -205,7 +205,7 @@ def test_write_data_success(opc, tag, data_type, data):
|
|||||||
)
|
)
|
||||||
assert result == 0.1
|
assert result == 0.1
|
||||||
opc.opc_repository['server1'].write_data.assert_called_once_with(
|
opc.opc_repository['server1'].write_data.assert_called_once_with(
|
||||||
tag, data, data_type, opc.logger, metadata
|
tag, data, data_type, metadata
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -298,7 +298,7 @@ def test_write_data_validate_connection_do_nothing(opc_repository):
|
|||||||
opc_repository.client.get_node.return_value = mock_node
|
opc_repository.client.get_node.return_value = mock_node
|
||||||
|
|
||||||
result = opc_repository.write_data(
|
result = opc_repository.write_data(
|
||||||
'ns=2;s=TestNode', 42.0, 'float', opc_repository.logger, metadata['metadata']
|
'ns=2;s=TestNode', 42.0, 'float', metadata['metadata']
|
||||||
)
|
)
|
||||||
|
|
||||||
opc_repository.validate_connection.assert_called_once()
|
opc_repository.validate_connection.assert_called_once()
|
||||||
@@ -313,7 +313,7 @@ def test_write_data_validate_connection_failed(opc_repository):
|
|||||||
opc_repository.error_count = 0
|
opc_repository.error_count = 0
|
||||||
|
|
||||||
result = opc_repository.write_data(
|
result = opc_repository.write_data(
|
||||||
'ns=2;s=TestNode', 42.0, 'float', opc_repository.logger, metadata['metadata']
|
'ns=2;s=TestNode', 42.0, 'float', metadata['metadata']
|
||||||
)
|
)
|
||||||
|
|
||||||
opc_repository.validate_connection.assert_called_once()
|
opc_repository.validate_connection.assert_called_once()
|
||||||
@@ -328,7 +328,7 @@ def test_write_data_get_node_failed(opc_repository):
|
|||||||
opc_repository.client.get_node = MagicMock(side_effect=Exception('Test error'))
|
opc_repository.client.get_node = MagicMock(side_effect=Exception('Test error'))
|
||||||
|
|
||||||
is_success, error_data = opc_repository.write_data(
|
is_success, error_data = opc_repository.write_data(
|
||||||
'ns=2;s=TestNode', 42.0, 'float', opc_repository.logger, metadata['metadata']
|
'ns=2;s=TestNode', 42.0, 'float', metadata['metadata']
|
||||||
)
|
)
|
||||||
|
|
||||||
opc_repository.validate_connection.assert_called_once()
|
opc_repository.validate_connection.assert_called_once()
|
||||||
@@ -344,7 +344,7 @@ def test_write_data_invalid_data_type(opc_repository, mock_client):
|
|||||||
mock_client.get_node = MagicMock(return_value=mock_node)
|
mock_client.get_node = MagicMock(return_value=mock_node)
|
||||||
|
|
||||||
is_success, error_data = opc_repository.write_data(
|
is_success, error_data = opc_repository.write_data(
|
||||||
'ns=2;s=TestNode', 42.0, 'invalid_type', opc_repository.logger, metadata['metadata']
|
'ns=2;s=TestNode', 42.0, 'invalid_type', metadata['metadata']
|
||||||
)
|
)
|
||||||
|
|
||||||
opc_repository.validate_connection.assert_called_once()
|
opc_repository.validate_connection.assert_called_once()
|
||||||
@@ -361,7 +361,7 @@ def test_write_data(opc_repository, mock_client):
|
|||||||
mock_client.get_node = MagicMock(return_value=mock_node)
|
mock_client.get_node = MagicMock(return_value=mock_node)
|
||||||
|
|
||||||
result = opc_repository.write_data(
|
result = opc_repository.write_data(
|
||||||
'ns=2;s=TestNode', 42.0, 'float', opc_repository.logger, metadata['metadata']
|
'ns=2;s=TestNode', 42.0, 'float', metadata['metadata']
|
||||||
)
|
)
|
||||||
|
|
||||||
mock_client.get_node.assert_called_once_with('ns=2;s=TestNode')
|
mock_client.get_node.assert_called_once_with('ns=2;s=TestNode')
|
||||||
@@ -378,7 +378,7 @@ def test_write_data_write_value_failed(opc_repository, mock_client):
|
|||||||
mock_node.set_value.side_effect = Exception('Test error')
|
mock_node.set_value.side_effect = Exception('Test error')
|
||||||
|
|
||||||
is_success, error_data = opc_repository.write_data(
|
is_success, error_data = opc_repository.write_data(
|
||||||
'ns=2;s=TestNode', 42.0, 'float', opc_repository.logger, metadata['metadata']
|
'ns=2;s=TestNode', 42.0, 'float', metadata['metadata']
|
||||||
)
|
)
|
||||||
|
|
||||||
opc_repository.validate_connection.assert_called_once()
|
opc_repository.validate_connection.assert_called_once()
|
||||||
|
|||||||
Reference in New Issue
Block a user