from temporalio import activity, workflow with workflow.unsafe.imports_passed_through(): from logging import Logger from sientia_do.notifications.handlers import NotificationHandler from laborious.activities.base import BaseActivity from laborious.utils.repository.opc_repository import OpcRepository from typing import Any from sientia_do.notifications.models import NotificationLevel import traceback from pandas import DataFrame class OPC(BaseActivity): def __init__(self, name: str, url: str, server_uri: str, cert_path: str, private_key_path: str, server_cert_path: str, logger: Logger, notification_handler: NotificationHandler): self.logger = logger self.notification_handler = notification_handler self.name = name self.url = url self.server_uri = server_uri self.cert_path = cert_path self.private_key_path = private_key_path self.server_cert_path = server_cert_path self.opc_repository = OpcRepository( name=self.name, url=self.url, logger=self.logger, server_uri=self.server_uri, cert_path=self.cert_path, private_key_path=self.private_key_path, server_cert_path=self.server_cert_path ) self.opc_repository.connect() @activity.defn(name='write_opc_data') async def write_opc_data(self, input_data: dict[str, Any]): """ Write prediction and confidence data to OPC servers. The two writing operations are optional and independent of each other. Args: input_data (dict[str, Any]): The input data. Contains the following keys: data (dict[str, Any]): The dataframe that contains the data to write to the OPC servers. opc_servers (list[str]): The OPC servers to write to. opc_output_config (dict[str, Any]): The OPC writing configuration. Contains: prediction_tags (dict[str, Any]): The tags to write to the OPC servers. confidence_tags (dict[str, Any]): The tags to write to the OPC servers. Returns: """ data = DataFrame(input_data['data']) _opc_servers = input_data['opc_servers'] opc_output_config = input_data['opc_output_config'] if 'prediction_tags' in opc_output_config: for tag, config in opc_output_config['prediction_tags'].items(): try: self.opc_repository.write_data( tag, data.head(1)['prediction'].values[0], config['data_type']) except Exception as e: trace = traceback.format_exc() self.notification_handler.build_and_send_notification( notification_id="WRITE_OPC_PREDICTION_ERROR", message=f"Error writing data to OPC server: {e}", block="write_opc_data", level=NotificationLevel.ERROR, attachment_content=trace ) self.logger.error(trace) if 'confidence_tags' in opc_output_config: for tag, config in opc_output_config['confidence_tags'].items(): try: self.opc_repository.write_data( tag, data.head(1)['prediction_confidence'].values[0], config['data_type']) except Exception as e: trace = traceback.format_exc() self.notification_handler.build_and_send_notification( notification_id="WRITE_OPC_CONFIDENCE_ERROR", message=f"Error writing data to OPC server: {e}", block="write_opc_data", level=NotificationLevel.ERROR, attachment_content=trace ) self.logger.error(trace)