FUNCTION_BLOCK "ReadServerDiagnostics"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT 
      read { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
   END_VAR

   VAR_OUTPUT 
      done { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
      busy { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
      error { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
      status { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : DWord;
      server { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : "typeServer";
      simaticDevice { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : "typeSimaticDevice";
   END_VAR

   VAR 
      statConnectionHdl { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : DWord := -42;
      statNodeCount { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : UInt := #NODES_COUNT;
      statNodeIds {InstructionName := 'OPC_UA_NodeId'; LibVersion := '1.0'; ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'; S7_SetPoint := 'False'} : Array[0..#NODES_UPPERBOUND] of OPC_UA_NodeId := [((), WSTRING#'2256', ()), ((), WSTRING#'2255', ()), ((), WSTRING#'2275', ()), ((), WSTRING#'3707', ()), ((), WSTRING#'3708', ()), ((), WSTRING#'2290', ()), ((), WSTRING#'2254', ()), (3, WSTRING#'DeviceManual', 1), (3, WSTRING#'DeviceRevision', 1), (3, WSTRING#'EngineeringRevision', 1), (3, WSTRING#'HardwareRevision', 1), (3, WSTRING#'Manufacturer', 1), (3, WSTRING#'Model', 1), (3, WSTRING#'OperatingMode', 1), (3, WSTRING#'OrderNumber', 1), (3, WSTRING#'RevisionCounter', 1), (3, WSTRING#'SerialNumber', 1), (3, WSTRING#'SoftwareRevision', 1), ((), WSTRING#'11702', ()), ((), WSTRING#'2735', ()), ((), WSTRING#'12911', ()), ((), WSTRING#'2737', ()), ((), WSTRING#'2736', ()), ((), WSTRING#'11703', ()), ((), WSTRING#'2272', ()), ((), WSTRING#'11714', ()), ((), WSTRING#'11710', ()), ((), WSTRING#'11709', ()), ((), WSTRING#'11705', ()), ((), WSTRING#'11711', ()), ((), WSTRING#'11712', ()), ((), WSTRING#'11707', ()), ((), WSTRING#'2269', ())];
      statNodeStatusList { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Array[0..#NODES_UPPERBOUND] of DWord;
      statTimeStamps { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Array[0..#NODES_UPPERBOUND] of LDT;
      statVariable { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Struct
         ServerStatus { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'; S7_SetPoint := 'False'} : "typeServerStatus";
         NamespaceArray { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Array[0.."NAMESPACEARRAY_UPPERBOUND"] of String;
         ServerDiagnosticsSummary { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'; S7_SetPoint := 'False'} : "typeServerDiagnosticsSummary";
         SessionDiagnosticsArray { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'; S7_SetPoint := 'False'} : Array[0.."SESSIONS_UPPERBOUND"] of "typeSessionDiagnostics";
         SessionSecurityDiagnosticsArray { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'; S7_SetPoint := 'False'} : Array[0.."SESSIONS_UPPERBOUND"] of "typeSessionSecurityDiagnosticsData";
         SubscriptionDiagnosticsArray { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'; S7_SetPoint := 'False'} : Array[0.."SUBSCRIPTIONS_UPPERBOUND"] of "typeSubscriptionDiagnostics";
         ServerArray { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Array[0.."SERVERARRAY_UPPERBOUND"] of String;
         DeviceManual { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : String;
         DeviceRevision { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : String;
         EngineeringRevision { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : String;
         HardwareRevision { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : String;
         Manufacturer { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'; S7_SetPoint := 'False'} : "typeLocalizedText" := (16#0002, (), ());
         Model { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'; S7_SetPoint := 'False'} : "typeLocalizedText" := (16#0002, (), ());
         OperatingMode { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : DInt;
         OrderNumber { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : String;
         RevisionCounter { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : DInt;
         SerialNumber { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : String;
         SoftwareRevision { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : String;
         MaxArrayLength { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : UDInt;
         MaxBrowseContinuationPoints { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : UInt;
         MaxByteStringLength { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : UDInt;
         MaxHistoryContinuationPoints { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : UInt;
         MaxQueryContinuationPoints { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : UInt;
         MaxStringLength { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : UDInt;
         MinSupportedSampleRate { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : LReal;
         MaxMonitoredItemsPerCall { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : UDInt;
         MaxNodesPerBrowse { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : UDInt;
         MaxNodesPerMethodCall { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : UDInt;
         MaxNodesPerRead { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : UDInt;
         MaxNodesPerRegisterNodes { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : UDInt;
         MaxNodesPerTranslateBrowsePathsToNodeIds { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : UDInt;
         MaxNodesPerWrite { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : UDInt;
         ServerProfileArray { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Array[0.."SERVERPROFILES_UPPERBOUND"] of WString;
      END_STRUCT;
      instOpcUaReadList {InstructionName := 'OPC_UA_ReadList'; LibVersion := '1.0'; ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'; S7_SetPoint := 'False'} : OPC_UA_ReadList;
   END_VAR

   VAR_TEMP 
      tempDone : Bool;
      tempBusy : Bool;
      tempError : Bool;
      tempStatus : DWord;
   END_VAR

   VAR CONSTANT 
      NODES_UPPERBOUND : DInt := 32;
      NODES_COUNT : UInt := 33;
   END_VAR


BEGIN
	REGION Description header
	    //==================================================================================
	    // SIEMENS / (C) Copyright 2023
	    //----------------------------------------------------------------------------------
	    // Title: ReadServerDiagnostics
	    // Comment/Function: reads out the Server node data of the internal OPC UA server
	    // Library/Family: 
	    // Author: SIEMENS SIMATIC Systems Support (SUP)
	    // Target System: 
	    // Engineering: TIA Portal (>= V18)
	    // Restrictions: 
	    // Requirements: FW 3.0 (1500)
	    //----------------------------------------------------------------------------------
	    // Change log table:
	    // Version | Date | Expert in charge | Changes applied
	    //-------------|------------|------------------|------------------------------------
	    // 001.000.000 | 2023-02-13 | SUP SPH | First released version
	    //==================================================================================
	END_REGION Description header
	
	REGION OPC_UA_ReadList instance
	    #instOpcUaReadList(REQ := #read,
	                       ConnectionHdl := #statConnectionHdl,
	                       NodeHdlCount := #statNodeCount,
	                       NodeHdls := #statNodeIds,
	                       Done => #tempDone,
	                       Busy => #tempBusy,
	                       Error => #tempError,
	                       Status => #tempStatus,
	                       NodeStatusList := #statNodeStatusList,
	                       TimeStamps := #statTimeStamps,
	                       Variable := #statVariable);
	END_REGION OPC_UA_ReadList instance
	
	REGION Write results
	    IF #tempDone THEN
	        
	        //ServerStatus
	        #server.serverStatus := #statVariable.ServerStatus;
	        
	        //NamespaceArray
	        #server.namespaceArray := #statVariable.NamespaceArray;
	        
	        //ServerArray
	        #server.serverArray := #statVariable.ServerArray;
	        
	        //Diagnostics
	        #server.serverDiagnostics.serverDiagnosticsSummary := #statVariable.ServerDiagnosticsSummary;
	        #server.serverDiagnostics.sessionDiagnosticsArray := #statVariable.SessionDiagnosticsArray;
	        #server.serverDiagnostics.sessionSecurityDiagnosticsArray := #statVariable.SessionSecurityDiagnosticsArray;
	        #server.serverDiagnostics.subscriptionDiagnosticsArray := #statVariable.SubscriptionDiagnosticsArray;
	        
	        //ServerCapabilities:
	        #server.serverCapabilities.MaxArrayLength := #statVariable.MaxArrayLength;
	        #server.serverCapabilities.MaxBrowseContinuationPoints := #statVariable.MaxBrowseContinuationPoints;
	        #server.serverCapabilities.MaxByteStringLength := #statVariable.MaxByteStringLength;
	        #server.serverCapabilities.MaxHistoryContinuationPoints := #statVariable.MaxHistoryContinuationPoints;
	        #server.serverCapabilities.MaxQueryContinuationPoints := #statVariable.MaxQueryContinuationPoints;
	        #server.serverCapabilities.MaxStringLength := #statVariable.MaxStringLength;
	        #server.serverCapabilities.MinSupportedSampleRate := #statVariable.MinSupportedSampleRate;
	        #server.serverCapabilities.OperationLimits.MaxMonitoredItemsPerCall := #statVariable.MaxMonitoredItemsPerCall;
	        #server.serverCapabilities.OperationLimits.MaxNodesPerBrowse := #statVariable.MaxNodesPerBrowse;
	        #server.serverCapabilities.OperationLimits.MaxNodesPerMethodCall := #statVariable.MaxNodesPerMethodCall;
	        #server.serverCapabilities.OperationLimits.MaxNodesPerRead := #statVariable.MaxNodesPerRead;
	        #server.serverCapabilities.OperationLimits.MaxNodesPerRegisterNodes := #statVariable.MaxNodesPerRegisterNodes;
	        #server.serverCapabilities.OperationLimits.MaxNodesPerTranslateBrowsePathsToNodeIds := #statVariable.MaxNodesPerTranslateBrowsePathsToNodeIds;
	        #server.serverCapabilities.OperationLimits.MaxNodesPerWrite := #statVariable.MaxNodesPerWrite;
	        #server.serverCapabilities.ServerProfileArray := #statVariable.ServerProfileArray;
	        
	        //SimaticDevice
	        #simaticDevice.#deviceManual := STRING_TO_WSTRING(#statVariable.DeviceManual);
	        #simaticDevice.#deviceRevision := STRING_TO_WSTRING(#statVariable.DeviceRevision);
	        #simaticDevice.#engineeringRevision := STRING_TO_WSTRING(#statVariable.EngineeringRevision);
	        #simaticDevice.#hardwareRevision := STRING_TO_WSTRING(#statVariable.HardwareRevision);
	        #simaticDevice.manufacturer := #statVariable.Manufacturer;
	        #simaticDevice.#model := #statVariable.Model;
	        #simaticDevice.#orderNumber := STRING_TO_WSTRING(#statVariable.OrderNumber);
	        #simaticDevice.#revisionCounter := #statVariable.RevisionCounter;
	        #simaticDevice.#serialNumber := STRING_TO_WSTRING(#statVariable.SerialNumber);
	        #simaticDevice.#softwareRevision := STRING_TO_WSTRING(#statVariable.SoftwareRevision);
	        
	    END_IF;
	    
	END_REGION  Write results
	
	REGION Outputs
	    
	    //simply pass output parameters
	    #done := #tempDone;
	    #error := #tempError;
	    #status := #tempStatus;
	    #busy := #tempBusy;
	    
	END_REGION Outputs
END_FUNCTION_BLOCK

