Refactor Activities and API Integration for PI Web API - Reintroduced the API import in the Activities class for proper integration. - Cleaned up whitespace and formatting in the API class and related tests for improved readability. - Updated test cases to ensure consistent formatting in error messages and configuration structures for PI Web API. - Enhanced connectors_config.py with additional whitespace for better organization.
141 lines
5.1 KiB
Python
141 lines
5.1 KiB
Python
from temporalio import activity, workflow
|
|
|
|
with workflow.unsafe.imports_passed_through():
|
|
import traceback
|
|
from typing import Any
|
|
|
|
from pandas import DataFrame
|
|
from sientia_do.notifications.handlers import NotificationHandler
|
|
from sientia_do.notifications.models import NotificationLevel
|
|
from sientia_do.observability.logger import Logger
|
|
from sientia_do.observability.metrics_controller import MetricsController
|
|
from sientia_do.observability.sientia_monitoring import SientiaMonitoring
|
|
from sientia_do.repository.pi_web_api_client import PIWebAPIClient
|
|
|
|
|
|
PI_WEB_API_PREDICTION_ERROR_CONFIDENCE = 13
|
|
|
|
|
|
class API(SientiaMonitoring):
|
|
"""
|
|
PI Web API operations for writing data to PI Web API.
|
|
|
|
This class provides Temporal activities for interacting with the PI Web API
|
|
to write data to PI Web API.
|
|
"""
|
|
|
|
def __init__(
|
|
self,
|
|
base_url: str,
|
|
auth_type: str,
|
|
auth_token: str,
|
|
logger: Logger,
|
|
notification_handler: NotificationHandler,
|
|
metrics_controller: MetricsController,
|
|
) -> None:
|
|
"""
|
|
Initialize API activity with PI Web API client.
|
|
|
|
Args:
|
|
base_url (str): Base URL of the PI Web API server
|
|
auth_type (str): Authentication type ('basic' or 'bearer')
|
|
auth_token (str): Authentication token
|
|
logger (Logger): Logger instance for operation logging
|
|
notification_handler (NotificationHandler): Handler for system notifications
|
|
metrics_controller (MetricsController): Controller for metrics collection
|
|
"""
|
|
SientiaMonitoring.__init__(self, logger, notification_handler, metrics_controller)
|
|
self.pi_web_api_client = PIWebAPIClient(
|
|
base_url=base_url,
|
|
auth_config={
|
|
'type': auth_type,
|
|
'token': auth_token,
|
|
},
|
|
logger=logger,
|
|
notification_handler=notification_handler,
|
|
metrics_controller=metrics_controller,
|
|
)
|
|
|
|
def close(self) -> None:
|
|
"""
|
|
Close the PI Web API client and shutdown monitoring services.
|
|
"""
|
|
self.pi_web_api_client.close()
|
|
SientiaMonitoring.shutdown(self)
|
|
|
|
@activity.defn(name='write_pi_web_api_data')
|
|
async def write_pi_web_api_data(self, input_data: dict[str, Any]) -> dict[Any, Any]:
|
|
"""
|
|
Write data to PI Web API.
|
|
|
|
Args:
|
|
input_data (dict[str, Any]): The input data. Containing:
|
|
- metadata (dict[str, Any]): The metadata.
|
|
- pi_web_api_output_config (dict[str, Any]): The PI Web API output configuration.
|
|
- data (dict[str, Any]): The data to write.
|
|
"""
|
|
metadata = input_data['metadata']
|
|
data = DataFrame(input_data['data'])
|
|
pi_web_api_output_config = input_data['pi_web_api_output_config']
|
|
|
|
self.info('Writing data to PI Web API...', metadata)
|
|
|
|
endpoint = pi_web_api_output_config['endpoint']
|
|
|
|
raw_prediction_tags = pi_web_api_output_config['prediction_tags']
|
|
raw_confidence_tags = pi_web_api_output_config['confidence_tags']
|
|
prediction_tags = list[str](raw_prediction_tags.values())
|
|
confidence_tags = list[str](raw_confidence_tags.values())
|
|
|
|
prediction_value = data.head(1)['prediction'].values[0]
|
|
confidence_value = data.head(1)['prediction_confidence'].values[0]
|
|
|
|
try:
|
|
await self.pi_web_api_client.write_value(
|
|
web_ids=prediction_tags,
|
|
value={
|
|
'Timestamp': data.head(1)['timestamp'].values[0],
|
|
'Value': prediction_value,
|
|
},
|
|
endpoint=endpoint,
|
|
metadata=metadata,
|
|
)
|
|
|
|
except Exception as e:
|
|
trace = traceback.format_exc()
|
|
await self.send_notification_async(
|
|
metadata=metadata,
|
|
notification_id='WRITE_PI_WEB_API_PREDICTION_ERROR',
|
|
message=f'Error writing prediction data to PI Web API: {e}\n Tags: {raw_prediction_tags}',
|
|
block='write_pi_web_api_data',
|
|
level=NotificationLevel.ERROR,
|
|
attachment_content=trace,
|
|
)
|
|
|
|
data['prediction_confidence'] = PI_WEB_API_PREDICTION_ERROR_CONFIDENCE
|
|
|
|
return data.to_dict()
|
|
|
|
try:
|
|
await self.pi_web_api_client.write_value(
|
|
web_ids=confidence_tags,
|
|
value={
|
|
'Timestamp': data.head(1)['timestamp'].values[0],
|
|
'Value': confidence_value,
|
|
},
|
|
endpoint=endpoint,
|
|
metadata=metadata,
|
|
)
|
|
except Exception as e:
|
|
trace = traceback.format_exc()
|
|
await self.send_notification_async(
|
|
metadata=metadata,
|
|
notification_id='WRITE_PI_WEB_API_CONFIDENCE_ERROR',
|
|
message=f'Error writing confidence data to PI Web API: {e}\n Tags: {raw_confidence_tags}',
|
|
block='write_pi_web_api_data',
|
|
level=NotificationLevel.ERROR,
|
|
attachment_content=trace,
|
|
)
|
|
|
|
return data.to_dict()
|