Projektdateien hinzufügen.

This commit is contained in:
Matthias Heisig
2024-01-04 15:15:26 +01:00
parent 4c6f8dc5bd
commit faa33db290
94 changed files with 15104 additions and 0 deletions

155
PLC/POUs/FB_Module.TcPOU Normal file
View File

@@ -0,0 +1,155 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.12">
<POU Name="FB_Module" Id="{87be924f-018d-4c09-997b-f0c0054414cc}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK FB_Module
VAR_INPUT
// Emergency stop ok
xEmergencyStopOk : BOOL;
// HMI Interface
stHMIInterface : REFERENCE TO ST_MODULE_HMI_INTERFACE;
// Release alarms
xReleaseErrors : BOOL;
// Release analog io limit errors
xReleaseLimitErrors : BOOL;
// Input to confirm all errors
xConfirmAlarms : BOOL;
END_VAR
VAR_OUTPUT
// One unit has an error
xError : BOOL;
// One unit has a warning
xWarning : BOOL;
END_VAR
VAR
_fbUnit1 : FB_Unit(CONCAT(_sName, ' Unit 1'));
_fbUnit2 : FB_Unit(CONCAT(_sName, ' Unit 2'));
_fbUnit3 : FB_Unit(CONCAT(_sName, ' Unit 3'));
_fbUnit4 : FB_Unit(CONCAT(_sName, ' Unit 4'));
// Module name
_sName : STRING;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// Reset error and warning flag
xError := FALSE;
xWarning := FALSE;
// ===============================
// Unit 1
// ===============================
_fbUnit1(
stUnitConfig:= GVL_CONFIG.stUnitConfig,
stHMIInterface:= stHMIInterface.stHMIInterfaceUnit1,
xEmergencyStopOk:= xEmergencyStopOk,
rSetpointPosolytPumpInlet:= GVL_CONFIG.rPumpPosolytOnPower,
rSetpointNegolytPumpInlet:= GVL_CONFIG.rPumpNegolytOnPower,
xReleaseErrors:= xReleaseErrors,
xReleaseLimitErrors:= xReleaseLimitErrors,
xConfirmAlarms:= xConfirmAlarms,
_xWarningConfirmPending=> );
IF _fbUnit1.xWarning THEN
xWarning := TRUE;
END_IF
IF _fbUnit1.xError THEN
xError := TRUE;
END_IF
// ===============================
// Unit 2
// ===============================
_fbUnit2(
stUnitConfig:= GVL_CONFIG.stUnitConfig,
stHMIInterface:= stHMIInterface.stHMIInterfaceUnit2,
xEmergencyStopOk:= xEmergencyStopOk,
rSetpointPosolytPumpInlet:= GVL_CONFIG.rPumpPosolytOnPower,
rSetpointNegolytPumpInlet:= GVL_CONFIG.rPumpNegolytOnPower,
xReleaseErrors:= xReleaseErrors,
xReleaseLimitErrors:= xReleaseLimitErrors,
xConfirmAlarms:= xConfirmAlarms,
_xWarningConfirmPending=> );
IF _fbUnit2.xWarning THEN
xWarning := TRUE;
END_IF
IF _fbUnit2.xError THEN
xError := TRUE;
END_IF
// ===============================
// Unit 3
// ===============================
_fbUnit3(
stUnitConfig:= GVL_CONFIG.stUnitConfig,
stHMIInterface:= stHMIInterface.stHMIInterfaceUnit3,
xEmergencyStopOk:= xEmergencyStopOk,
rSetpointPosolytPumpInlet:= GVL_CONFIG.rPumpPosolytOnPower,
rSetpointNegolytPumpInlet:= GVL_CONFIG.rPumpNegolytOnPower,
xReleaseErrors:= xReleaseErrors,
xReleaseLimitErrors:= xReleaseLimitErrors,
xConfirmAlarms:= xConfirmAlarms,
_xWarningConfirmPending=> );
IF _fbUnit3.xWarning THEN
xWarning := TRUE;
END_IF
IF _fbUnit3.xError THEN
xError := TRUE;
END_IF
// ===============================
// Unit 4
// ===============================
_fbUnit4(
stUnitConfig:= GVL_CONFIG.stUnitConfig,
stHMIInterface:= stHMIInterface.stHMIInterfaceUnit4,
xEmergencyStopOk:= xEmergencyStopOk,
rSetpointPosolytPumpInlet:= GVL_CONFIG.rPumpPosolytOnPower,
rSetpointNegolytPumpInlet:= GVL_CONFIG.rPumpNegolytOnPower,
xReleaseErrors:= xReleaseErrors,
xReleaseLimitErrors:= xReleaseLimitErrors,
xConfirmAlarms:= xConfirmAlarms,
_xWarningConfirmPending=> );
IF _fbUnit4.xWarning THEN
xWarning := TRUE;
END_IF
IF _fbUnit4.xError THEN
xError := TRUE;
END_IF]]></ST>
</Implementation>
<Method Name="FB_init" Id="{369c1d27-76e4-45f8-9dbe-03524d3389df}">
<Declaration><![CDATA[METHOD FB_init : BOOL
VAR_INPUT
bInitRetains : BOOL; // if TRUE, the retain variables are initialized (warm start / cold start)
bInCopyCode : BOOL; // if TRUE, the instance afterwards gets moved into the copy code (online change)
sName : STRING;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[_sName := sName;]]></ST>
</Implementation>
</Method>
<LineIds Name="FB_Module">
<LineId Id="248" Count="92" />
<LineId Id="188" Count="0" />
</LineIds>
<LineIds Name="FB_Module.FB_init">
<LineId Id="7" Count="0" />
</LineIds>
</POU>
</TcPlcObject>

124
PLC/POUs/FB_String.TcPOU Normal file
View File

@@ -0,0 +1,124 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.12">
<POU Name="FB_String" Id="{46501225-f446-4674-bfed-3be64273e576}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK FB_String
VAR_INPUT
// Module 1 HMI interface
stHMIInterface : ST_STRING_HMI_INTERFACE;
// Emergency stop ok
xEmergencyStopOk : BOOL;
// Release alarms
xReleaseErrors : BOOL;
// Release analog io limit errors
xReleaseLimitErrors : BOOL;
// Input to confirm all errors
xConfirmAlarms : BOOL;
END_VAR
VAR_OUTPUT
xError : BOOL;
xWarning : BOOL;
END_VAR
VAR
_fbModule1 : FB_Module(CONCAT(_sName, 'Module 1'));
_fbModule2 : FB_Module(CONCAT(_sName, 'Module 2'));
_fbModule3 : FB_Module(CONCAT(_sName, 'Module 3'));
// String name
_sName : STRING;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// ===============================
// Module 1
// ===============================
_fbModule1(
xEmergencyStopOk:= xEmergencyStopOk,
stHMIInterface:= stHMIInterface.stHMIInterfaceModule1,
xReleaseErrors:= xReleaseErrors,
xReleaseLimitErrors:= xReleaseLimitErrors,
xConfirmAlarms:= xConfirmAlarms);
IF _fbModule1.xWarning THEN
xWarning := TRUE;
END_IF
IF _fbModule1.xError THEN
xError := TRUE;
END_IF
// ===============================
// Module 2
// ===============================
_fbModule2(
xEmergencyStopOk:= xEmergencyStopOk,
stHMIInterface:= stHMIInterface.stHMIInterfaceModule2,
xReleaseErrors:= xReleaseErrors,
xReleaseLimitErrors:= xReleaseLimitErrors,
xConfirmAlarms:= xConfirmAlarms);
IF _fbModule2.xWarning THEN
xWarning := TRUE;
END_IF
IF _fbModule2.xError THEN
xError := TRUE;
END_IF
// ===============================
// Module 3
// ===============================
_fbModule3(
xEmergencyStopOk:= xEmergencyStopOk,
stHMIInterface:= stHMIInterface.stHMIInterfaceModule3,
xReleaseErrors:= xReleaseErrors,
xReleaseLimitErrors:= xReleaseLimitErrors,
xConfirmAlarms:= xConfirmAlarms);
IF _fbModule3.xWarning THEN
xWarning := TRUE;
END_IF
IF _fbModule3.xError THEN
xError := TRUE;
END_IF]]></ST>
</Implementation>
<Method Name="FB_init" Id="{9e8494eb-1b40-4be9-91c8-810ecbdf7f0c}">
<Declaration><![CDATA[METHOD FB_init : BOOL
VAR_INPUT
bInitRetains : BOOL; // if TRUE, the retain variables are initialized (warm start / cold start)
bInCopyCode : BOOL; // if TRUE, the instance afterwards gets moved into the copy code (online change)
sName : STRING;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[_sName := sName;]]></ST>
</Implementation>
</Method>
<LineIds Name="FB_String">
<LineId Id="69" Count="0" />
<LineId Id="67" Count="1" />
<LineId Id="47" Count="1" />
<LineId Id="50" Count="3" />
<LineId Id="58" Count="0" />
<LineId Id="62" Count="0" />
<LineId Id="64" Count="0" />
<LineId Id="66" Count="0" />
<LineId Id="63" Count="0" />
<LineId Id="59" Count="2" />
<LineId Id="71" Count="17" />
<LineId Id="70" Count="0" />
<LineId Id="90" Count="17" />
<LineId Id="89" Count="0" />
</LineIds>
<LineIds Name="FB_String.FB_init">
<LineId Id="7" Count="0" />
</LineIds>
</POU>
</TcPlcObject>

535
PLC/POUs/FB_Unit.TcPOU Normal file
View File

@@ -0,0 +1,535 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.12">
<POU Name="FB_Unit" Id="{e9bb815b-eb46-4920-800d-910484e58b22}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK FB_Unit
VAR_INPUT
// Unit configuration
stUnitConfig : REFERENCE TO ST_UNIT_CONFIG;
// HMI interface
stHMIInterface : REFERENCE TO ST_UNIT_HMI_INTERFACE;
// Start unit
xEnable : BOOL;
// Emergency stop ok
xEmergencyStopOk : BOOL;
// Setpoint posolyt pump inlet
rSetpointPosolytPumpInlet : REAL;
// Setpoint negolyt pump inlet
rSetpointNegolytPumpInlet : REAL;
// Release alarms
xReleaseErrors : BOOL;
// Release analog io limit errors
xReleaseLimitErrors : BOOL;
// Input to confirm all errors
xConfirmAlarms : BOOL;
END_VAR
VAR_OUTPUT
// Unit ready
xReady : BOOL;
// Error active
xError : BOOL;
// Warning active
xWarning : BOOL;
// Warning confirmation still pending
_xWarningConfirmPending : BOOL;
END_VAR
VAR
// Check unit condition after some time during startup
_timUnitStartupWaitTime : TIME := T#20S;
// Valves posolyt
_fbPosolytValveTankOutlet : FB_Valve('Posolyt tank outlet');
// Valves negolyt
_fbNegolytValveTankOutlet : FB_Valve('Negolyt tank outlet');
// Pumps posolyt
_fbPosolytPumpInlet : FB_MotorAnalog('Posolyt segment inlet');
// Pumps negolyt
_fbNegolytPumpInlet : FB_MotorAnalog('Negolyt segment inlet');
// Pressure sensors posolyt
_fbPressurePosolytSegmentInlet : FB_AnalogInput('P1_P');
_fbPressurePosolytTankInlet : FB_AnalogInput('P3_P');
_fbPressurePosolytTankOutlet : FB_AnalogInput('P4_P');
// Pressure sensors negolyt
_fbPressureNegolytSegmentInlet : FB_AnalogInput('P1_N');
_fbPressureNegolytTankInlet : FB_AnalogInput('P3_N');
_fbPressureNegolytTankOutlet : FB_AnalogInput('P4_N');
// Unit voltage
_fbVoltageSegment : FB_AnalogInput('Voltage');
// Valve posolyt tank outlet interlocks
_stPosolytValveTankOutletPIntlk : T_INTERLOCK;
_stPosolytValveTankOutletPIntlkUsed : T_INTERLOCK := 2#0000_0000_0000_0000;
_stPosolytValveTankOutletSIntlk : T_INTERLOCK;
_stPosolytValveTankOutletSIntlkUsed : T_INTERLOCK := 2#0000_0000_0000_0011;
// Valve negolyt tank outlet interlocks
_stNegolytValveTankOutletPIntlk : T_INTERLOCK;
_stNegolytValveTankOutletPIntlkUsed : T_INTERLOCK := 2#0000_0000_0000_0000;
_stNegolytValveTankOutletSIntlk : T_INTERLOCK;
_stNegolytValveTankOutletSIntlkUsed : T_INTERLOCK := 2#0000_0000_0000_0011;
// Pump posolyt inlet interlocks
_stPosolytPumpInletPIntlk : T_INTERLOCK;
_stPosolytPumpInletPIntlkUsed : T_INTERLOCK := 2#0000_0000_0000_0001;
_stPosolytPumpInletSIntlk : T_INTERLOCK;
_stPosolytPumpInletSIntlkUsed : T_INTERLOCK := 2#0000_0000_0000_0011;
// Pump negolyt inlet interlocks
_stNegolytPumpInletPIntlk : T_INTERLOCK;
_stNegolytPumpInletPIntlkUsed : T_INTERLOCK := 2#0000_0000_0000_0001;
_stNegolytPumpInletSIntlk : T_INTERLOCK;
_stNegolytPumpInletSIntlkUsed : T_INTERLOCK := 2#0000_0000_0000_0011;
// Error active
_xErrorActive : BOOL;
// Warning active
_xWarningActive : BOOL;
// Current state
_iState: INT;
// All components in automatic mode
_xAllComponentsInAutomatic : BOOL;
// Not all components in automatic mode alarm
_fbNotAllAutomaticAlarm : FB_TcAlarm;
// Unit name
_sName : STRING;
// Unit startup check timer
_tonStartupCheck : TON;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// Reset error active
_xErrorActive := FALSE;
// Reset warning active
_xWarningActive := FALSE;
// ===============================
// Valve posolyt tank outlet
// ===============================
// Safety Interlocks
stHMIInterface.stPosolytValve.stInterlock.asSafetyINTLKName[0] := 'Emergency stop ok';
_stPosolytValveTankOutletSIntlk.0 := xEmergencyStopOk;
// Valve fb
_fbPosolytValveTankOutlet(
xReleaseManualMode:= TRUE,
wProcessINTLK:= _stPosolytValveTankOutletPIntlk,
wProcessINTLKUsed:= _stPosolytValveTankOutletPIntlkUsed,
wSafetyINTLK:= _stPosolytValveTankOutletSIntlk,
wSafetyINTLKUsed:= _stPosolytValveTankOutletSIntlkUsed,
xConfirmAlarms:= xConfirmAlarms,
xReleaseErrors:= xReleaseErrors,
stValveConfig:= stUnitConfig.stConfigPosolytValve,
stHMIInterface:= stHMIInterface.stPosolytValve);
// Set error active if fb has error
IF _fbPosolytValveTankOutlet.xError THEN
_xErrorActive := TRUE;
END_IF
// ===============================
// Valve negolyt tank outlet
// ===============================
// Safety Interlocks
stHMIInterface.stNegolytValve.stInterlock.asSafetyINTLKName[0] := 'Emergency stop ok';
_stNegolytValveTankOutletSIntlk.0 := xEmergencyStopOk;
// Valve fb
_fbNegolytValveTankOutlet(
xReleaseManualMode:= TRUE,
wProcessINTLK:= _stNegolytValveTankOutletPIntlk,
wProcessINTLKUsed:= _stNegolytValveTankOutletPIntlkUsed,
wSafetyINTLK:= _stNegolytValveTankOutletSIntlk,
wSafetyINTLKUsed:= _stNegolytValveTankOutletSIntlkUsed,
xConfirmAlarms:= xConfirmAlarms,
xReleaseErrors:= xReleaseErrors,
stValveConfig:= stUnitConfig.stConfigNegolytValve,
stHMIInterface:= stHMIInterface.stNegolytValve);
// Set error active if fb has error
IF _fbNegolytValveTankOutlet.xError THEN
_xErrorActive := TRUE;
END_IF
// ===============================
// Pump posolyt segment inlet
// ===============================
// Safety Interlocks
stHMIInterface.stPosolytPump.stInterlock.asSafetyINTLKName[0] := 'Emergency stop ok';
_stPosolytPumpInletSIntlk.0 := xEmergencyStopOk;
// Process interlocks
stHMIInterface.stPosolytPump.stInterlock.asProcessINTLKName[0] := 'At least one valve is open';
_stPosolytPumpInletPIntlk.0 := _fbPosolytValveTankOutlet.IsOpen;
// Valve fb
_fbPosolytPumpInlet(
xReleaseManualMode:= TRUE,
wProcessINTLK:= _stPosolytPumpInletPIntlk,
wProcessINTLKUsed:= _stPosolytPumpInletPIntlkUsed,
wSafetyINTLK:= _stPosolytPumpInletSIntlk,
wSafetyINTLKUsed:= _stPosolytPumpInletSIntlkUsed,
xReleaseErrors:= xReleaseErrors,
xConfirmAlarms:= xConfirmAlarms,
rSPautomatic:= rSetpointPosolytPumpInlet,
xReleaseAnalogInLimitErrors:= xReleaseLimitErrors,
stMotorAnalogConfig:= stUnitConfig.stConfigPosolytPump,
stHMIInterface:= stHMIInterface.stPosolytPump,
xWarning=> );
// Set error active if fb has error
IF _fbPosolytPumpInlet.xError THEN
_xErrorActive := TRUE;
END_IF
// Set warning if fb has warning
IF _fbPosolytPumpInlet.xWarning THEN
_xWarningActive := TRUE;
END_IF
// ===============================
// Pump negolyt segment inlet
// ===============================
// Safety Interlocks
stHMIInterface.stNegolytPump.stInterlock.asSafetyINTLKName[0] := 'Emergency stop ok';
_stNegolytPumpInletSIntlk.0 := xEmergencyStopOk;
// Process interlocks
stHMIInterface.stNegolytPump.stInterlock.asProcessINTLKName[0] := 'At least one valve is open';
_stNegolytPumpInletPIntlk.0 := _fbNegolytValveTankOutlet.IsOpen;
// Valve fb
_fbNegolytPumpInlet(
xReleaseManualMode:= TRUE,
wProcessINTLK:= _stNegolytPumpInletPIntlk,
wProcessINTLKUsed:= _stNegolytPumpInletPIntlkUsed,
wSafetyINTLK:= _stNegolytPumpInletSIntlk,
wSafetyINTLKUsed:= _stNegolytPumpInletSIntlkUsed,
xReleaseErrors:= xReleaseErrors,
xConfirmAlarms:= xConfirmAlarms,
rSPautomatic:= rSetpointNegolytPumpInlet,
xReleaseAnalogInLimitErrors:= xReleaseLimitErrors,
stMotorAnalogConfig:= stUnitConfig.stConfigNegolytPump,
stHMIInterface:= stHMIInterface.stNegolytPump,
xWarning=> );
// Set error active if fb has error
IF _fbNegolytPumpInlet.xError THEN
_xErrorActive := TRUE;
END_IF
// Set warning if fb has warning
IF _fbNegolytPumpInlet.xWarning THEN
_xWarningActive := TRUE;
END_IF
// ===============================
// Pressure sensors posolyt segment inlet
// ===============================
_fbPressurePosolytSegmentInlet(
stScalingConfig:= stUnitConfig.stConfigPosolytPressureSegmentInlet,
stEWConfig:= stUnitConfig.stEWLPosolytPressureSegmentInlet,
stEWDelayConfig:= stUnitConfig.stEWDPosolytPressureSegmentInlet,
xReleaseErrors:= xReleaseErrors,
xReleaseLimitErrors:= xReleaseLimitErrors,
xReleaseHardwareErrors:= xReleaseErrors,
xConfirmAlarms:= xConfirmAlarms,
stHMIInterface => stHMIInterface.stPosolytPressureSegmentInlet);
// Set error active if fb has error
IF _fbPressurePosolytSegmentInlet.xError THEN
_xErrorActive := TRUE;
END_IF
// Set warning if fb has warning
IF _fbPressurePosolytSegmentInlet.xWarning THEN
_xWarningActive := TRUE;
END_IF
// ===============================
// Pressure sensors negolyt segment inlet
// ===============================
_fbPressureNegolytSegmentInlet(
stScalingConfig:= stUnitConfig.stConfigNegolytPressureSegmentInlet,
stEWConfig:= stUnitConfig.stEWLNegolytPressureSegmentInlet,
stEWDelayConfig:= stUnitConfig.stEWDNegolytPressureSegmentInlet,
xReleaseErrors:= xReleaseErrors,
xReleaseLimitErrors:= xReleaseLimitErrors,
xReleaseHardwareErrors:= xReleaseErrors,
xConfirmAlarms:= xConfirmAlarms,
stHMIInterface => stHMIInterface.stNegolytPressureSegmentInlet);
// Set error active if fb has error
IF _fbPressureNegolytSegmentInlet.xError THEN
_xErrorActive := TRUE;
END_IF
// Set warning if fb has warning
IF _fbPressureNegolytSegmentInlet.xWarning THEN
_xWarningActive := TRUE;
END_IF
// ===============================
// Voltage segment
// ===============================
_fbVoltageSegment(
stScalingConfig:= ,
stEWConfig:= ,
stEWDelayConfig:= ,
xReleaseErrors:= xReleaseErrors,
xReleaseLimitErrors:= xReleaseLimitErrors,
xReleaseHardwareErrors:= xReleaseErrors,
xConfirmAlarms:= xConfirmAlarms,
stHMIInterface=> stHMIInterface.stVoltageSegment);
// Set error active if fb has error
IF _fbVoltageSegment.xError THEN
_xErrorActive := TRUE;
END_IF
// Set warning if fb has warning
IF _fbVoltageSegment.xWarning THEN
_xWarningActive := TRUE;
END_IF
// ===============================
// Check if all components are in automatic
// ===============================
_xAllComponentsInAutomatic := _fbPosolytValveTankOutlet.IsInAutomaticMode
AND _fbNegolytValveTankOutlet.IsInAutomaticMode
AND _fbPosolytPumpInlet.IsInAutomaticMode
AND _fbNegolytPumpInlet.IsInAutomaticMode;
// Raise warning
IF NOT _fbNotAllAutomaticAlarm.bRaised AND (NOT _xAllComponentsInAutomatic) THEN
_fbNotAllAutomaticAlarm.Raise(0);
END_IF
// Clear warning and reset
IF _fbNotAllAutomaticAlarm.bRaised AND _xAllComponentsInAutomatic THEN
_fbNotAllAutomaticAlarm.Clear(0, TRUE);
END_IF
// ===============================
// Run state machine for startup and shutdown
// ===============================
CASE _iState OF
0: // Off
IF xEnable AND _xAllComponentsInAutomatic AND (NOT _xErrorActive) THEN
_iState := 10;
END_IF
10: // Open all valves
_fbPosolytValveTankOutlet.ReqAutomaticOpen();
_fbNegolytValveTankOutlet.ReqAutomaticOpen();
_iState := 15;
15: // Wait for all valves to be open
IF _fbPosolytValveTankOutlet.IsOpen AND _fbNegolytValveTankOutlet.IsOpen THEN
IF NOT _fbPosolytValveTankOutlet.xError AND _fbNegolytValveTankOutlet.xError THEN
_iState := 20;
END_IF
END_IF
// If enable signal is lost, or there is an error, goto shutdown
IF (NOT xEnable) OR _xErrorActive THEN
_iState := 40;
END_IF
20: // Start pumps
_fbPosolytPumpInlet.ReqAutomaticStart();
_fbNegolytPumpInlet.ReqAutomaticStart();
_iState := 25;
25: // Wait for all pumps to run
IF _fbPosolytPumpInlet.xInTarget AND _fbNegolytPumpInlet.xInTarget THEN
_iState := 30;
END_IF
// If enable signal is lost, goto shutdown
IF (NOT xEnable) OR _xErrorActive THEN
_iState := 40;
END_IF
30: // Wait some time
_tonStartupCheck(In := TRUE, PT := _timUnitStartupWaitTime);
// After some time, check if all values are ok
IF _tonStartupCheck.Q THEN
// Check for minimum unit voltage
IF _fbVoltageSegment.rScaledValue >= GVL_CONFIG.rMinimumUnitVoltage AND
NOT _xErrorActive AND
NOT _xWarningActive THEN
xReady := TRUE;
_iState := 35;
ELSE
_iState := 40;
END_IF
END_IF
// If enable signal is lost, goto shutdown
IF (NOT xEnable) OR _xErrorActive THEN
_iState := 40;
END_IF
35: // Unit in enabled state
IF (NOT xEnable) OR _xErrorActive THEN
_iState := 40;
END_IF
40: // Close all valves
_fbNegolytValveTankOutlet.ReqAutomaticClose();
_fbPosolytValveTankOutlet.ReqAutomaticClose();
_iState := 45;
45: // Wait for valves to be closed
IF _fbNegolytValveTankOutlet.IsClosed AND _fbPosolytValveTankOutlet.IsClosed THEN
_iState := 50;
END_IF
// When there is an error trying to close the valves,
// dont try to discharge the segment
IF _fbNegolytValveTankOutlet.xError OR _fbPosolytValveTankOutlet.xError THEN
_iState := 60;
END_IF
// Check for restart condition
IF xEnable AND (NOT _xErrorActive) THEN
_iState := 0;
END_IF
50: // Wait for unit voltage to drop below a certain threshold
IF (_fbVoltageSegment.rScaledValue <= GVL_CONFIG.rPumpshutoffThreshold) THEN
_iState := 60;
END_IF
// Check for restart condition
IF xEnable AND (NOT _xErrorActive) THEN
_iState := 0;
END_IF
60: // Disable pumps
_fbPosolytPumpInlet.ReqAutomaticStop();
_fbNegolytPumpInlet.ReqAutomaticStop();
_iState := 65;
65: // Wait for pumps to be stopped
IF _fbPosolytPumpInlet.IsStopped AND _fbNegolytPumpInlet.IsStopped THEN
IF _xErrorActive THEN
_iState := 1000;
ELSE
_iState := 0;
END_IF
END_IF
// Check for restart condition
IF xEnable AND (NOT _xErrorActive) THEN
_iState := 0;
END_IF
1000: // Alarm active
// Only allow reset when enable is deactivated to avoid an
// automatic restart of the unit
IF (NOT _xErrorActive) AND (NOT xEnable) THEN
_iState := 0;
END_IF
END_CASE
// ===============================
// Output error and warning flags
// ===============================
xError := _xErrorActive;
xWarning := _xWarningActive;]]></ST>
</Implementation>
<Method Name="FB_init" Id="{08f1cd44-6483-4d20-ab45-d1938e8ec885}">
<Declaration><![CDATA[METHOD FB_init : BOOL
VAR_INPUT
bInitRetains : BOOL; // if TRUE, the retain variables are initialized (warm start / cold start)
bInCopyCode : BOOL; // if TRUE, the instance afterwards gets moved into the copy code (online change)
sName : STRING;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[_sName := sName;
_fbNotAllAutomaticAlarm.CreateEx(TC_EVENTS.General.NotAllCompInAutomatic, bWithConfirmation := FALSE, 0);
_fbNotAllAutomaticAlarm.ipArguments.Clear().AddString(_sName);]]></ST>
</Implementation>
</Method>
<LineIds Name="FB_Unit">
<LineId Id="4232" Count="29" />
<LineId Id="4584" Count="0" />
<LineId Id="4263" Count="102" />
<LineId Id="4619" Count="0" />
<LineId Id="4367" Count="46" />
<LineId Id="4621" Count="22" />
<LineId Id="4620" Count="0" />
<LineId Id="4644" Count="1" />
<LineId Id="4414" Count="0" />
<LineId Id="4647" Count="0" />
<LineId Id="4646" Count="0" />
<LineId Id="4416" Count="17" />
<LineId Id="4444" Count="26" />
<LineId Id="4476" Count="33" />
<LineId Id="4511" Count="17" />
<LineId Id="4653" Count="0" />
<LineId Id="4655" Count="2" />
<LineId Id="4654" Count="0" />
<LineId Id="4529" Count="4" />
<LineId Id="4658" Count="0" />
<LineId Id="4660" Count="2" />
<LineId Id="4659" Count="0" />
<LineId Id="4569" Count="0" />
<LineId Id="4535" Count="12" />
<LineId Id="4663" Count="0" />
<LineId Id="4665" Count="2" />
<LineId Id="4664" Count="0" />
<LineId Id="4548" Count="6" />
<LineId Id="4556" Count="6" />
<LineId Id="2754" Count="0" />
</LineIds>
<LineIds Name="FB_Unit.FB_init">
<LineId Id="11" Count="1" />
<LineId Id="7" Count="1" />
</LineIds>
</POU>
</TcPlcObject>

28
PLC/POUs/MAIN.TcPOU Normal file
View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.12">
<POU Name="MAIN" Id="{bbd7302c-91ce-4697-9f4b-743f57ca5819}" SpecialFunc="None">
<Declaration><![CDATA[PROGRAM MAIN
VAR
_xEmergencyStopOk AT %I* : BOOL;
_xReleaseErrors : BOOL;
_xReleaseLimitsErrors : BOOL;
_xConfirmAlarms : BOOL;
_fbString : FB_String('String 1');
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[_fbString(
stHMIInterface:= ,
xEmergencyStopOk:= _xEmergencyStopOk,
xReleaseErrors:= _xReleaseErrors,
xReleaseLimitErrors:= _xReleaseLimitsErrors,
xConfirmAlarms:= _xConfirmAlarms,
xError=> ,
xWarning=> );]]></ST>
</Implementation>
<LineIds Name="MAIN">
<LineId Id="7" Count="6" />
<LineId Id="2" Count="0" />
</LineIds>
</POU>
</TcPlcObject>

View File

@@ -0,0 +1,628 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.12">
<POU Name="FB_PowerSupplySunspec" Id="{a826dd09-442c-45c5-8ae3-9b71f293003c}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK FB_PowerSupplySunspec
VAR_INPUT
sInverterIPAddr : STRING;
xEnable : BOOL;
rPower : REAL;
xReset : BOOL;
rMaxBattPower : REAL := 24_000; // 24kW
END_VAR
VAR_OUTPUT
xCloseDCRelais AT %Q*: BOOL;
rActDCCurrent : REAL;
rActDCVoltage : REAL;
xError : BOOL;
xActive : BOOL;
END_VAR
VAR
// Current state
_iState : INT := 0;
// FB for reading Modbus holding registers
_fbReadRegister : FB_MBReadRegs;
// FB for writing Modbus holding registers
_fbWriteRegister : FB_MBWriteRegs;
// Timer for checking if the inverter started in a reasonable amount of time
_tonInverterStartup : TON;
// converter max power scaling factor
_iWMaxSF : INT;
// Unscaled converter max power
_iWMax : UINT;
// Scaled converter max power
_rWMax : REAL;
// Unscaled limit for converter power
_iWMaxLimPct : INT;
// Scaling factor for power limiting
_iWMaxLimPctSF : INT;
// Unscaled maximum power from type label
_iWRTGSF : INT;
// Scaling for maximum power from type label
_rWRTGScaling : REAL;
// Current state of the inverters internal statemachine
_uiInverterState : UINT;
// Last written power to the inverter
_rOldPower : REAL;
// Value to enable or dissable the Power limiting feature
_uiMaxLimEn : UINT;
// Value for commanding the target state of the inverter
_uiPCSSetOperation : UINT;
// Holds the state number in which an error occured
_iErrorInState : INT;
// Time for polling for current dc values and check for inverter error
_timPollingDelay : TIME := T#250MS;
// Timer for polling of current values
_tonPollingTimer : TON;
// Current DC values (DCA, DCA_SF, DCV, DCV_SF) in word array for efficient modbus reading
_awCurrentDCValues : ARRAY[0..3] OF WORD;
// Inverter error bits
_dwErrorBits : DWORD;
// Inverter reset errors command
_uiResetInverter : UINT := 1;
END_VAR
VAR CONSTANT
// Inverter statemachine status register
// Size 1, enum16 (Range = 0 .. 65534, Not implemented = 0xFFFF)
STATUS_REGISTER : WORD := 40108;
// Throttled power register
// Size 1, int16 (Range = -32767 .. 32767, Not implemented 0x8000)
W_MAX_LIM_PCT_REGISTER : WORD := 40187;
// Throttled power register scaling factor
// Size 1, sunssf (int16) (Range = -10 .. 10, Not implemented 0x8000)
W_MAX_LIM_PCT_SF_REGISTER : WORD := 40205;
// Control register to enable and dissable if the power throttleing should be active
// Size1, enum16 (Range = 0 .. 65534, Not implemented = 0xFFFF)
W_MAX_LIM_EN_REGISTER : WORD := 40191;
// Register to reset latched alarms in the inverter
// Size 1, uint16 (Range = 0 .. 65534, Not implemented = 0xFFFF)
PCS_ALARM_RESET_REGISTER : WORD := 40230;
// Control register to set the target state of the inverters state machine
// Size 1, enum16 (Range = 0 .. 65534, Not implemented = 0xFFFF)
PCS_SET_OPERATION_REGISTER : WORD := 40231;
// Maximum inverter output power
// Size 1, uint16 (Range = 0 .. 65534, Not implemented = 0xFFFF)
W_MAX_REGISTER : WORD := 40152;
// Maximum inverter output power scaling factor
// Size 1, sunssf (int16) (Range = -10 .. 10, Not implemented 0x8000)
W_MAX_SF_REGISTER : WORD := 40172;
// Maximum inverter output power from type label
// Size 1, uint16 (Range = 0 .. 65534, Not implemented = 0xFFFF)
W_RTG_REGISTER : WORD := 40125;
// Maximum inverter output power from type label scaling factor
// Size 1, sunssf (int16) (Range = -10 .. 10, Not implemented 0x8000)
W_RTG_SF_REGISTER : WORD := 40126;
// Start of register with the current dc values
// Size 4
DC_VALUES_START_REGISTER : WORD := 40097;
// Error bits register
// Size 2
EVT_1_REGISTER : WORD := 40110;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// Clamp rPower to maximum allowed power
IF (rPower > rMaxBattPower) THEN
rPower := rMaxBattPower;
END_IF
IF (rPower < -rMaxBattPower) THEN
rPower := -rMaxBattPower;
END_IF
// State machine
CASE _iState OF
0: // Off
// If enable and INTLK Ok
IF xEnable THEN
_iState := 10;
xCloseDCRelais := TRUE;
END_IF
10: // Wait for inverter to be online and in state STANDBY(8)
_fbReadRegister(
sIPAddr:= sInverterIPAddr,
nTCPPort:= 502,
nUnitID:= 16#FF, // 16#FF for Modbus TCP
nQuantity:= 1,
nMBAddr:= STATUS_REGISTER,
cbLength:= SIZEOF(_uiInverterState),
pDestAddr:= ADR(_uiInverterState),
bExecute:= TRUE,
tTimeout:= T#5S,
bBusy=> ,
bError=> ,
nErrId=> ,
cbRead=> );
// Check if reading mudbus register is done
IF NOT _fbReadRegister.bBusy THEN
// If there was no error and the state is STANDBY(8) then continue
IF NOT _fbReadRegister.bError AND _uiInverterState = 8 THEN
_iState := 20;
END_IF
_fbReadRegister(bExecute := FALSE);
END_IF
20: // Read inverter max power scaling
_iErrorInState := _iState;
_fbReadRegister(
sIPAddr:= sInverterIPAddr,
nTCPPort:= 502,
nUnitID:= 16#FF, // 16#FF for Modbus TCP
nQuantity:= 1,
nMBAddr:= W_MAX_SF_REGISTER,
cbLength:= SIZEOF(_iWMaxSF),
pDestAddr:= ADR(_iWMaxSF),
bExecute:= TRUE,
tTimeout:= T#5S,
bBusy=> ,
bError=> ,
nErrId=> ,
cbRead=> );
// Check if reading mudbus register is done
IF NOT _fbReadRegister.bBusy THEN
// If there was no error then continue
IF NOT _fbReadRegister.bError THEN
_iState := 25;
// Check for valid value
IF (_iWMaxSF < -10) OR (_iWMaxSF > 10) OR (_iWMaxSF = 16#8000) THEN
// Goto error state
_iState := 1000;
END_IF
ELSE
xError := TRUE;
// Goto error state
_iState := 1000;
END_IF
_fbReadRegister(bExecute := FALSE);
END_IF
25: // Read inverter Max power limit scaling
_iErrorInState := _iState;
_fbReadRegister(
sIPAddr:= sInverterIPAddr,
nTCPPort:= 502,
nUnitID:= 16#FF, // 16#FF for Modbus TCP
nQuantity:= 1,
nMBAddr:= W_MAX_LIM_PCT_SF_REGISTER,
cbLength:= SIZEOF(_iWMaxLimPctSF),
pDestAddr:= ADR(_iWMaxLimPctSF),
bExecute:= TRUE,
tTimeout:= T#5S,
bBusy=> ,
bError=> ,
nErrId=> ,
cbRead=> );
// Check if reading mudbus register is done
IF NOT _fbReadRegister.bBusy THEN
// If there was no error then continue
IF NOT _fbReadRegister.bError THEN
_iState := 30;
// Check for valid value
IF (_iWMaxLimPctSF < -10) OR (_iWMaxLimPctSF > 10) OR (_iWMaxLimPctSF = 16#8000) THEN
// Goto error state
_iState := 1000;
END_IF
ELSE
xError := TRUE;
// Goto error state
_iState := 1000;
END_IF
_fbReadRegister(bExecute := FALSE);
END_IF
30: // Read inverter max power
_iErrorInState := _iState;
_fbReadRegister(
sIPAddr:= sInverterIPAddr,
nTCPPort:= 502,
nUnitID:= 16#FF, // 16#FF for Modbus TCP
nQuantity:= 1,
nMBAddr:= W_MAX_REGISTER,
cbLength:= SIZEOF(_iWMax),
pDestAddr:= ADR(_iWMax),
bExecute:= TRUE,
tTimeout:= T#5S,
bBusy=> ,
bError=> ,
nErrId=> ,
cbRead=> );
// Check if reading mudbus register is done
IF NOT _fbReadRegister.bBusy THEN
// If there was no error then continue
IF NOT _fbReadRegister.bError THEN
_iState := 40;
// Reading a register with scaling factor = value * 10^SF
_rWMax := _iWMax * EXPT(10,_iWMaxSF);
// Calculate power to write to register
_iWMaxLimPct := LREAL_TO_INT(rPower * EXPT(10,_iWMaxLimPctSF) / _rWMax);
ELSE
xError := TRUE;
// Goto error state
_iState := 1000;
END_IF
_fbReadRegister(bExecute := FALSE);
END_IF
40: // Set power limit
_iErrorInState := _iState;
_fbWriteRegister(
sIPAddr:= sInverterIPAddr,
nTCPPort:= 502,
nUnitID:= 16#FF, // 16#FF for Modbus TCP
nQuantity:= 1,
nMBAddr:= W_MAX_LIM_PCT_REGISTER,
cbLength:= SIZEOF(_iWMaxLimPct),
pSrcAddr:= ADR(_iWMaxLimPct),
bExecute:= TRUE,
tTimeout:= T#5S,
bBusy=> ,
bError=> ,
nErrId=> );
// If writing modbus register is done
IF NOT _fbWriteRegister.bBusy THEN
// And there is no error, then continue
IF NOT _fbWriteRegister.bError THEN
_iState := 50;
_rOldPower := rPower;
_uiMaxLimEn := 1;
ELSE
xError := TRUE;
// Goto error state
_iState := 1000;
END_IF
_fbWriteRegister(bExecute := FALSE);
END_IF
50: // Enable Power limiting (THROTTLED)
_iErrorInState := _iState;
_fbWriteRegister(
sIPAddr:= sInverterIPAddr,
nTCPPort:= 502,
nUnitID:= 16#FF, // 16#FF for Modbus TCP
nQuantity:= 1,
nMBAddr:= W_MAX_LIM_EN_REGISTER,
cbLength:= SIZEOF(_uiMaxLimEn),
pSrcAddr:= ADR(_uiMaxLimEn),
bExecute:= TRUE,
tTimeout:= T#5S,
bBusy=> ,
bError=> ,
nErrId=> );
// If writing modbus register is done
IF NOT _fbWriteRegister.bBusy THEN
// And there is no error, then continue
IF NOT _fbWriteRegister.bError THEN
_iState := 60;
_uiPCSSetOperation := 1;
ELSE
xError := TRUE;
// Goto error state
_iState := 1000;
END_IF
_fbWriteRegister(bExecute := FALSE);
END_IF
60: // Switch to THROTTLED mode
_iErrorInState := _iState;
_fbWriteRegister(
sIPAddr:= sInverterIPAddr,
nTCPPort:= 502,
nUnitID:= 16#FF, // 16#FF for Modbus TCP
nQuantity:= 1,
nMBAddr:= PCS_SET_OPERATION_REGISTER,
cbLength:= SIZEOF(_uiPCSSetOperation),
pSrcAddr:= ADR(_uiPCSSetOperation),
bExecute:= TRUE,
tTimeout:= T#5S,
bBusy=> ,
bError=> ,
nErrId=> );
// If writing modbus register is done
IF NOT _fbWriteRegister.bBusy THEN
// And there is no error, then continue
IF NOT _fbWriteRegister.bError THEN
_iState := 65;
ELSE
// Goto error state
_iState := 1000;
END_IF
_fbWriteRegister(bExecute := FALSE);
END_IF
65: // Wait for error polling timer
_tonPollingTimer(IN := TRUE, PT := _timPollingDelay);
IF _tonPollingTimer.Q THEN
_tonPollingTimer(IN := FALSE);
_iState := 70;
ELSIF ABS(rPower - _rOldPower) > 0.1 THEN
_tonPollingTimer(IN := FALSE);
// If power has ben changed, goto set power limit mode
_iState := 40;
END_IF
// check if inverter should shut down
IF NOT xEnable THEN
_uiPCSSetOperation := 3;
// Goto shutdown sequence
_iState := 200;
END_IF
70: // Enabled, check for error
_iErrorInState := _iState;
_fbReadRegister(
sIPAddr:= sInverterIPAddr,
nTCPPort:= 502,
nUnitID:= 16#FF, // 16#FF for Modbus TCP
nQuantity:= 1,
nMBAddr:= STATUS_REGISTER,
cbLength:= SIZEOF(_uiInverterState),
pDestAddr:= ADR(_uiInverterState),
bExecute:= TRUE,
tTimeout:= T#5S,
bBusy=> ,
bError=> ,
nErrId=> ,
cbRead=> );
// Check if reading mudbus register is done
IF NOT _fbReadRegister.bBusy THEN
// If there was no error and the converter has no error continue
IF NOT _fbReadRegister.bError AND (_uiInverterState <> 7) THEN
_iState := 80;
IF (_uiInverterState = 4) OR (_uiInverterState = 5) THEN
xActive := TRUE;
ELSE
xActive := FALSE;
END_IF
ELSE
xError := TRUE;
// Read error register
_iState := 990;
END_IF
_fbReadRegister(bExecute := FALSE);
END_IF
80: // Read current DC values
_iErrorInState := _iState;
_fbReadRegister(
sIPAddr:= sInverterIPAddr,
nTCPPort:= 502,
nUnitID:= 16#FF, // 16#FF for Modbus TCP
nQuantity:= 4,
nMBAddr:= DC_VALUES_START_REGISTER,
cbLength:= SIZEOF(_awCurrentDCValues),
pDestAddr:= ADR(_awCurrentDCValues),
bExecute:= TRUE,
tTimeout:= T#5S,
bBusy=> ,
bError=> ,
nErrId=> ,
cbRead=> );
// Check if reading mudbus register is done
IF NOT _fbReadRegister.bBusy THEN
// If there was no error and the converter has no error continue
IF NOT _fbReadRegister.bError THEN
_iState := 65;
rActDCCurrent := WORD_TO_UINT(_awCurrentDCValues[0]) * EXPT(10,WORD_TO_INT(_awCurrentDCValues[1]));
rActDCVoltage := WORD_TO_UINT(_awCurrentDCValues[2]) * EXPT(10,WORD_TO_INT(_awCurrentDCValues[3]));
ELSE
// Read error register
_iState := 1000;
END_IF
_fbReadRegister(bExecute := FALSE);
END_IF
200: // Shutdown sequence
_iErrorInState := _iState;
_fbWriteRegister(
sIPAddr:= sInverterIPAddr,
nTCPPort:= 502,
nUnitID:= 16#FF, // 16#FF for Modbus TCP
nQuantity:= 1,
nMBAddr:= PCS_SET_OPERATION_REGISTER,
cbLength:= SIZEOF(_uiPCSSetOperation),
pSrcAddr:= ADR(_uiPCSSetOperation),
bExecute:= TRUE,
tTimeout:= T#5S,
bBusy=> ,
bError=> ,
nErrId=> );
// If writing modbus register is done
IF NOT _fbWriteRegister.bBusy THEN
// And there is no error, then continue
IF NOT _fbWriteRegister.bError THEN
_iState := 210;
rActDCCurrent := 0.0;
rActDCVoltage := 0.0;
ELSE
// Goto error state
_iState := 1000;
END_IF
_fbWriteRegister(bExecute := FALSE);
END_IF
210: // Wait for poll timer to
_tonPollingTimer(IN := TRUE, PT := _timPollingDelay);
IF _tonPollingTimer.Q THEN
_tonPollingTimer(IN := FALSE);
_iState := 220;
END_IF
220: // Poll and wait for standby state
_iErrorInState := _iState;
_fbReadRegister(
sIPAddr:= sInverterIPAddr,
nTCPPort:= 502,
nUnitID:= 16#FF, // 16#FF for Modbus TCP
nQuantity:= 1,
nMBAddr:= STATUS_REGISTER,
cbLength:= SIZEOF(_uiInverterState),
pDestAddr:= ADR(_uiInverterState),
bExecute:= TRUE,
tTimeout:= T#5S,
bBusy=> ,
bError=> ,
nErrId=> ,
cbRead=> );
// Check if reading mudbus register is done
IF NOT _fbReadRegister.bBusy THEN
// If there was no error and the converter has no error continue
IF NOT _fbReadRegister.bError THEN
_iState := 0;
xActive := FALSE;
xCloseDCRelais := FALSE;
END_IF
_fbReadRegister(bExecute := FALSE);
END_IF
990: // Read error register
_iErrorInState := _iState;
_fbReadRegister(
sIPAddr:= sInverterIPAddr,
nTCPPort:= 502,
nUnitID:= 16#FF, // 16#FF for Modbus TCP
nQuantity:= 2,
nMBAddr:= EVT_1_REGISTER,
cbLength:= SIZEOF(_dwErrorBits),
pDestAddr:= ADR(_dwErrorBits),
bExecute:= TRUE,
tTimeout:= T#5S,
bBusy=> ,
bError=> ,
nErrId=> ,
cbRead=> );
// Check if reading mudbus register is done
IF NOT _fbReadRegister.bBusy THEN
// If there was no error and the converter has no error continue
IF NOT _fbReadRegister.bError THEN
_iState := 1000;
END_IF
_fbReadRegister(bExecute := FALSE);
END_IF
1000: // Error state, wait for reset
IF xReset AND (NOT xEnable) THEN
_iState := 1010;
END_IF
1010: // Try to clear all latched events
_fbWriteRegister(
sIPAddr:= sInverterIPAddr,
nTCPPort:= 502,
nUnitID:= 16#FF, // 16#FF for Modbus TCP
nQuantity:= 1,
nMBAddr:= PCS_ALARM_RESET_REGISTER,
cbLength:= SIZEOF(_uiResetInverter),
pSrcAddr:= ADR(_uiResetInverter),
bExecute:= TRUE,
tTimeout:= T#5S,
bBusy=> ,
bError=> ,
nErrId=> );
IF NOT _fbWriteRegister.bBusy THEN
_iState := 0;
_fbWriteRegister(bExecute := FALSE);
END_IF
END_CASE]]></ST>
</Implementation>
<LineIds Name="FB_PowerSupplySunspec">
<LineId Id="774" Count="70" />
<LineId Id="1171" Count="0" />
<LineId Id="845" Count="33" />
<LineId Id="1172" Count="0" />
<LineId Id="879" Count="33" />
<LineId Id="1173" Count="0" />
<LineId Id="913" Count="29" />
<LineId Id="1174" Count="0" />
<LineId Id="943" Count="28" />
<LineId Id="1175" Count="0" />
<LineId Id="972" Count="46" />
<LineId Id="1127" Count="0" />
<LineId Id="1019" Count="25" />
<LineId Id="1097" Count="1" />
<LineId Id="1100" Count="1" />
<LineId Id="1099" Count="0" />
<LineId Id="1045" Count="0" />
<LineId Id="1176" Count="0" />
<LineId Id="1046" Count="6" />
<LineId Id="1063" Count="20" />
<LineId Id="1090" Count="0" />
<LineId Id="1092" Count="0" />
<LineId Id="1084" Count="4" />
<LineId Id="1062" Count="0" />
<LineId Id="1093" Count="1" />
<LineId Id="1102" Count="19" />
<LineId Id="1166" Count="1" />
<LineId Id="1122" Count="4" />
<LineId Id="1054" Count="0" />
<LineId Id="1295" Count="4" />
<LineId Id="1128" Count="0" />
<LineId Id="1300" Count="1" />
<LineId Id="1129" Count="0" />
<LineId Id="1132" Count="20" />
<LineId Id="1163" Count="0" />
<LineId Id="1294" Count="0" />
<LineId Id="1161" Count="1" />
<LineId Id="1130" Count="1" />
<LineId Id="1055" Count="0" />
<LineId Id="1177" Count="20" />
<LineId Id="1199" Count="1" />
<LineId Id="1169" Count="0" />
<LineId Id="1265" Count="2" />
<LineId Id="1269" Count="3" />
<LineId Id="1274" Count="11" />
<LineId Id="1273" Count="0" />
<LineId Id="1289" Count="1" />
<LineId Id="1293" Count="0" />
<LineId Id="1291" Count="1" />
<LineId Id="1056" Count="0" />
<LineId Id="12" Count="0" />
</LineIds>
</POU>
</TcPlcObject>

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.12">
<DUT Name="U_SUNSPEC_ERROR" Id="{4000836c-9d7f-470c-9b50-f6d22b3eac05}">
<Declaration><![CDATA[TYPE U_SUNSPEC_ERROR :
UNION
xGroundFault : BOOL;
xDCOverVoltage : BOOL;
xACDisconnected : BOOL;
xDCDisconnected : BOOL;
xGridDisconnected : BOOL;
xCabinetOpen : BOOL;
xManualShutdown : BOOL;
xOverTemp : BOOL;
xOverFrequency : BOOL;
xUnderFrequency : BOOL;
xACOverVoltage : BOOL;
xACUnderVoltage : BOOL;
xBlownStringFuse : BOOL;
xUnderTemp : BOOL;
xMemoryLoss : BOOL;
xHWTestFailure : BOOL;
xOtherAlarm : BOOL;
xOtherWarning : BOOL;
END_UNION
END_TYPE
]]></Declaration>
</DUT>
</TcPlcObject>