added sync units for cabinet temperature, changes in modbus interface to EMS (1.0.4 and 1.0.5), added error counter to modbus communication, lot of changes to kaco (faults, consecutive errors, bms error messages), isolation error ledge, allowed startbalancing when on shutdown, tower light integration
1143 lines
32 KiB
XML
1143 lines
32 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4026.12">
|
|
<POU Name="FB_String" Id="{46501225-f446-4674-bfed-3be64273e576}" SpecialFunc="None">
|
|
<Declaration><![CDATA[FUNCTION_BLOCK FB_String
|
|
VAR_INPUT
|
|
// Enable
|
|
xEnable : BOOL;
|
|
|
|
// Release inverter power
|
|
xReleaseInverterPower : BOOL;
|
|
|
|
// String number for unit numbering starting with 0 for String 1
|
|
uiStringNumber : UINT;
|
|
|
|
// Error shutdown -> No discharge throught inverter
|
|
xErrorShutdown : BOOL;
|
|
|
|
// Start in balancing mode
|
|
xStartBalancing : BOOL;
|
|
|
|
// String in safety check mode
|
|
xInSafetyCheckMode : BOOL;
|
|
|
|
// Operating mode of string
|
|
eOperationMode : E_STRING_OPERATING_MODE;
|
|
|
|
// Requested inverter power
|
|
rPowerInverter : REAL;
|
|
|
|
// String HMI interface
|
|
stHMIInterface : REFERENCE TO ST_STRING_HMI_INTERFACE;
|
|
|
|
// Emergency stop ok
|
|
xEmergencyStopOk : BOOL;
|
|
|
|
// Reset Safety
|
|
xResetSafety : BOOL;
|
|
|
|
// Release alarms
|
|
xReleaseErrors : BOOL;
|
|
|
|
// Release analog io limit errors
|
|
xReleaseLimitErrors : BOOL;
|
|
|
|
// Release manual mode
|
|
xReleaseManualMode : BOOL;
|
|
|
|
// Input to confirm all errors
|
|
xConfirmAlarms : BOOL;
|
|
|
|
// Switch all components to manual mode
|
|
xAllToManualMode : BOOL;
|
|
|
|
// String inverter ip
|
|
sInverterIP : STRING;
|
|
|
|
xECWcState AT %I* : BOOL;
|
|
|
|
xIsolationOKL1 AT %I* : BOOL;
|
|
xIsolationOKL2 AT %I* : BOOL;
|
|
|
|
refuStringErrorsModbus : REFERENCE TO U_STRING_ERROR_REGISTER;
|
|
END_VAR
|
|
VAR_OUTPUT
|
|
// Repair switch closed
|
|
xRepairSwitchOk AT %I* : BOOL;
|
|
|
|
// Safety communication error
|
|
{attribute 'analysis' := '-33'}
|
|
xSafetyComError AT %I* : BOOL;
|
|
|
|
// All safetyinterlocks from safety plc are ok
|
|
xSafetyIntlksOk AT %I* : BOOL;
|
|
|
|
// All component safety interlocks are ok
|
|
xSafetyIntlksComponentsOk : BOOL;
|
|
|
|
// Current string voltage
|
|
rCurrentVoltage : REAL;
|
|
|
|
// Module in shutdown segment discharge mode
|
|
xInShutdownDischargeMode : BOOL;
|
|
|
|
// Module can be discharged during shutdown sequence
|
|
xShutdownDischargeAllowed : BOOL;
|
|
|
|
// String ready
|
|
xReady : BOOL;
|
|
|
|
// String completely off
|
|
xOff : BOOL;
|
|
|
|
// Signal to close dc circuit breaker
|
|
xCloseDCCB AT %Q* : BOOL;
|
|
|
|
// Signal that dc circuit breakers are closed
|
|
xDCCBOpen AT %I* : BOOL;
|
|
|
|
// Reset signal for safety dc circuit breaker
|
|
xResetSafetyDCCB AT %Q* : BOOL;
|
|
|
|
// All modules in automatic mode
|
|
xAllModulesInAutoMode : BOOL;
|
|
|
|
xError : BOOL;
|
|
xWarning : BOOL;
|
|
|
|
// Temperature control cabinet module 1 above 40 °C
|
|
xTempCabinetModule1Warning : BOOL;
|
|
|
|
// Temperature control cabinet module 2 above 40 °C
|
|
xTempCabinetModule2Warning : BOOL;
|
|
|
|
// Temperature control cabinet module 3 above 40 °C
|
|
xTempCabinetModule3Warning : BOOL;
|
|
|
|
eStatus : E_COMPONENT_STATUS;
|
|
|
|
// Inverter status data
|
|
stInverterData : ST_SUNSPEC_CURRENT_VALUES;
|
|
|
|
// Smallest segment voltage
|
|
rSmallestSegmentVoltage : REAL;
|
|
|
|
// Highest segment voltage
|
|
rHighestSegmentVoltage : REAL;
|
|
|
|
// Balancing done
|
|
xBalancingDone : BOOL;
|
|
END_VAR
|
|
VAR
|
|
_fbModule1 : FB_Module(CONCAT(Name,' - Module 1'));
|
|
_fbModule2 : FB_Module(CONCAT(Name,' - Module 2'));
|
|
_fbModule3 : FB_Module(CONCAT(Name,' - Module 3'));
|
|
|
|
// All modules are ready
|
|
_xAllModulesReady : BOOL;
|
|
|
|
|
|
// All modules in shutdown discharge mode
|
|
_xAllModulesInShutdownDischargeMode : BOOL;
|
|
|
|
// Flag for module balance checking
|
|
_xBalanceOk : BOOL;
|
|
|
|
// Modules out of balance alarm message
|
|
_fbModulesOutOfBalanceAlarm : Fb_TcAlarm;
|
|
|
|
// Safetyinterlocks pending alarm
|
|
_fbSafetyInterlocksNotOkAlarm : FB_TcAlarm;
|
|
|
|
// Inverter startup error
|
|
_fbInverterStartupTimeoutAlarm : FB_TcAlarm;
|
|
|
|
// DC Main switch not closed
|
|
_fbDCMainSwitchNotClosed : FB_TcAlarm;
|
|
|
|
// Connection to SCS lost
|
|
_fbSCSConnLost : FB_TcAlarm;
|
|
|
|
// Isolatio alarm
|
|
_fbIsolationAlarm : FB_TcAlarm;
|
|
|
|
// Safety interlock reset timeout
|
|
_fbSafetyIntlkTimeoutAlarm : FB_TcAlarm;
|
|
|
|
// Shutdown discharge stopped messages
|
|
_fbSDDCLevel : FB_TcMessage;
|
|
_fbSDUnitThreshold : FB_TcMessage;
|
|
|
|
// State for start and stop
|
|
_iState : INT := 0;
|
|
|
|
// Error timer for not closing dc relais
|
|
_tonErrorDCCBNotClosed : TON := (PT := T#5S);
|
|
|
|
// Delayed balance check signal
|
|
_fbBalanceNotOkSignal : FB_ReleaseSignal;
|
|
|
|
// String name
|
|
_sName : STRING;
|
|
|
|
// String inverter
|
|
//_fbInverter : FB_PowerSupplySunspec(Name);
|
|
_fbInverter : FB_PowerSupplyKaco(Name);
|
|
|
|
// Internal inverter power command
|
|
_rPowerInverterInternal : REAL;
|
|
|
|
// Enable inverter flag
|
|
_xEnableInverter : BOOL;
|
|
|
|
// Fault timer for inverter startup
|
|
_tonInverterStartupTimeout : TON := (PT := T#3M);
|
|
|
|
// Fault timer for inverter shutdown
|
|
_tonInverterShutdownError : TON := (PT := T#10S);
|
|
|
|
// Debug delay timer for inverter shutdown
|
|
_tonInverterShutdownDelay : TON := (PT := T#10S);
|
|
|
|
// Timer for Safety ok timeout
|
|
_tonSafetyOkTimeout : TON := (PT := T#2M);
|
|
|
|
// Analog input for string current measurement
|
|
_fbStringCurrent : FB_AnalogInput(CONCAT(Name,' - Current'));
|
|
|
|
_xErrorInverter : BOOL;
|
|
|
|
_xReleaseLimitErrorsInternal : BOOL;
|
|
|
|
_xReleaseSafetyIntlkErrors : BOOL;
|
|
|
|
// Balancing done
|
|
_xBalancingDone : BOOL;
|
|
|
|
// Enable modules internal signal
|
|
_xEnable : BOOL;
|
|
|
|
// Start balancing internal signal
|
|
_xStartBalancing : BOOL;
|
|
|
|
_xIsoErrorActive : BOOL;
|
|
_xIsoError : BOOL;
|
|
|
|
// Iso error timeout
|
|
_fbTONIsoError : TON;
|
|
|
|
// Internal SOC
|
|
_rSOC : REAL;
|
|
|
|
_fbTONDCSettlingTime : TON := (PT := T#10S);
|
|
|
|
_xErrorInternal : BOOL;
|
|
|
|
_fbSafetyResetImpulseGen : FB_Blinker := (rFrequency := 2.0);
|
|
|
|
END_VAR
|
|
|
|
VAR PERSISTENT
|
|
rCapacityWH : REAL;
|
|
rCapacityAH : REAL;
|
|
END_VAR
|
|
]]></Declaration>
|
|
<Implementation>
|
|
<ST><![CDATA[// Reset all modules in automatic mode
|
|
xAllModulesInAutoMode := TRUE;
|
|
|
|
_fbSafetyResetImpulseGen();
|
|
|
|
// ===============================
|
|
// DC current measurement
|
|
// ===============================
|
|
_fbStringCurrent(
|
|
stScalingConfig:= GVL_CONFIG.stConfigSCSCurrent,
|
|
stEWConfig:= GVL_CONFIG.stEWLSCSCurrent,
|
|
stEWDelayConfig:= GVL_CONFIG.stEWDSCSCurrent,
|
|
xReleaseErrors:= xReleaseErrors,
|
|
xReleaseLimitErrors:= FALSE,
|
|
xReleaseHardwareErrors:= xReleaseErrors,
|
|
xConfirmAlarms:= xConfirmAlarms,
|
|
xError=> ,
|
|
xWarning=> ,
|
|
rScaledValue=> ,
|
|
xErrorLow=> ,
|
|
xWarningLow=> ,
|
|
xWarningHigh=> ,
|
|
xErrorHigh=> ,
|
|
stHMIInterface=> );
|
|
|
|
// Copy scaled current value to HMI
|
|
stHMIInterface.rCurrent := _fbStringCurrent.stHMIInterface.rValue;
|
|
|
|
|
|
// ===============================
|
|
// Module 1
|
|
// ===============================
|
|
_fbModule1(
|
|
xEnable := _xEnable,
|
|
uiFirstUnitIndex := uiStringNumber * 12,
|
|
rCurrent := stHMIInterface.rCurrent,
|
|
xStartBalancing := _xStartBalancing,
|
|
eStringOperatingMode := eOperationMode,
|
|
xInverterEnabled := _fbInverter.xActive,
|
|
xInSafetyCheckMode := xInSafetyCheckMode,
|
|
xEmergencyStopOk:= xEmergencyStopOk,
|
|
refstHMIInterface:= stHMIInterface.stHMIInterfaceModule1,
|
|
xReleaseErrors:= xReleaseErrors,
|
|
xReleaseLimitErrors:= xReleaseLimitErrors AND _xReleaseLimitErrorsInternal,
|
|
xReleaseManualMode := xReleaseManualMode,
|
|
xConfirmAlarms:= xConfirmAlarms,
|
|
xAllToManualMode := xAllToManualMode,
|
|
rBalancingTargetVoltage := rSmallestSegmentVoltage,
|
|
xTempCabinetWarning => xTempCabinetModule1Warning);
|
|
|
|
|
|
// ===============================
|
|
// Module 2
|
|
// ===============================
|
|
_fbModule2(
|
|
xEnable := _xEnable,
|
|
uiFirstUnitIndex := uiStringNumber * 12 + 4,
|
|
rCurrent := stHMIInterface.rCurrent,
|
|
xStartBalancing := _xStartBalancing,
|
|
eStringOperatingMode := eOperationMode,
|
|
xInverterEnabled := _fbInverter.xActive,
|
|
xInSafetyCheckMode := xInSafetyCheckMode,
|
|
xEmergencyStopOk:= xEmergencyStopOk,
|
|
refstHMIInterface:= stHMIInterface.stHMIInterfaceModule2,
|
|
xReleaseErrors:= xReleaseErrors,
|
|
xReleaseLimitErrors:= xReleaseLimitErrors AND _xReleaseLimitErrorsInternal,
|
|
xReleaseManualMode := xReleaseManualMode,
|
|
xConfirmAlarms:= xConfirmAlarms,
|
|
xAllToManualMode := xAllToManualMode,
|
|
rBalancingTargetVoltage := rSmallestSegmentVoltage,
|
|
xTempCabinetWarning => xTempCabinetModule2Warning);
|
|
|
|
|
|
// ===============================
|
|
// Module 3
|
|
// ===============================
|
|
_fbModule3(
|
|
xEnable := _xEnable,
|
|
uiFirstUnitIndex := uiStringNumber * 12 + 8,
|
|
rCurrent := stHMIInterface.rCurrent,
|
|
xStartBalancing := _xStartBalancing,
|
|
eStringOperatingMode := eOperationMode,
|
|
xInverterEnabled := _fbInverter.xActive,
|
|
xInSafetyCheckMode := xInSafetyCheckMode,
|
|
xEmergencyStopOk:= xEmergencyStopOk,
|
|
refstHMIInterface:= stHMIInterface.stHMIInterfaceModule3,
|
|
xReleaseErrors:= xReleaseErrors,
|
|
xReleaseLimitErrors:= xReleaseLimitErrors AND _xReleaseLimitErrorsInternal,
|
|
xReleaseManualMode := xReleaseManualMode,
|
|
xConfirmAlarms:= xConfirmAlarms,
|
|
xAllToManualMode := xAllToManualMode,
|
|
rBalancingTargetVoltage := rSmallestSegmentVoltage,
|
|
xTempCabinetWarning => xTempCabinetModule3Warning);
|
|
|
|
|
|
// ===============================
|
|
// Handle modules warning state
|
|
// ===============================
|
|
xWarning := _fbModule1.xWarning OR _fbModule2.xWarning OR _fbModule3.xWarning;
|
|
|
|
// ===============================
|
|
// Handle modules in auto mode
|
|
// ===============================
|
|
xAllModulesInAutoMode := _fbModule1.xAllUnitsInAutomatic AND _fbModule2.xAllUnitsInAutomatic AND _fbModule3.xAllUnitsInAutomatic;
|
|
|
|
// ===============================
|
|
// Handle shutdown discharge mode
|
|
// ===============================
|
|
_xAllModulesInShutdownDischargeMode := _fbModule1.xInShutdownDischargeMode AND _fbModule2.xInShutdownDischargeMode AND _fbModule3.xInShutdownDischargeMode;
|
|
|
|
// ===============================
|
|
// Modules ready check
|
|
// ===============================
|
|
_xAllModulesReady := _fbModule1.xReady AND _fbModule2.xReady AND _fbModule3.xReady;
|
|
|
|
// ===============================
|
|
// Balancing done check
|
|
// ===============================
|
|
_xBalancingDone := _fbModule1.xBalancingDone AND _fbModule2.xBalancingDone AND _fbModule3.xBalancingDone;
|
|
|
|
// ===============================
|
|
// Modules in shutdown discharge mode
|
|
// ===============================
|
|
xInShutdownDischargeMode := _fbModule1.xInShutdownDischargeMode OR _fbModule2.xInShutdownDischargeMode OR _fbModule3.xInShutdownDischargeMode;
|
|
|
|
// ===============================
|
|
// Units shutdown discharge allowed
|
|
// ===============================
|
|
xShutdownDischargeAllowed := _fbModule1.xShutdownDischargeAllowed AND _fbModule2.xShutdownDischargeAllowed AND _fbModule3.xShutdownDischargeAllowed;
|
|
|
|
// ===============================
|
|
// All modules off
|
|
// ===============================
|
|
xOff := _fbModule1.xOff AND _fbModule2.xOff AND _fbModule3.xOff;
|
|
|
|
// ===============================
|
|
// Call inverter
|
|
// ===============================
|
|
_fbInverter(
|
|
sInverterIPAddr:= sInverterIP,
|
|
xEnable:= _xEnableInverter AND xEmergencyStopOk,
|
|
xReleasePower := xReleaseInverterPower,
|
|
rPower:= _rPowerInverterInternal,
|
|
xReset:= xConfirmAlarms,
|
|
rMaxBattPower:= DINT_TO_REAL(GVL_CONFIG.diMaxStringDischargePower),
|
|
stCurrentValues => stInverterData);
|
|
|
|
refuStringErrorsModbus.stBitmap.bInverterError := _fbInverter.xError;
|
|
|
|
IF (_iState >= 30) AND (_iState < 40) THEN
|
|
rCapacityAH := rCapacityAH + ((stInverterData.rActDCCurrent * 0.01) / 3600);
|
|
rCapacityWH := rCapacityWH + ((stInverterData.rActACPower * 0.01) / 3600);
|
|
END_IF
|
|
|
|
// ===============================
|
|
// String ready validation check
|
|
// ===============================
|
|
_tonErrorDCCBNotClosed();
|
|
_tonSafetyOkTimeout();
|
|
|
|
|
|
// ===============================
|
|
// Get smalles segment voltage
|
|
// of all units
|
|
// ===============================
|
|
rSmallestSegmentVoltage := MIN(_fbModule1.rSmallestSegmentVoltage, _fbModule2.rSmallestSegmentVoltage, _fbModule3.rSmallestSegmentVoltage);
|
|
rHighestSegmentVoltage := MAX(_fbModule1.rHighestSegmentVoltage, _fbModule2.rHighestSegmentVoltage, _fbModule3.rHighestSegmentVoltage);
|
|
|
|
// Only recalculate SOC if all modules are ready
|
|
IF _xAllModulesReady THEN
|
|
_rSOC := ((100.0 * rSmallestSegmentVoltage ) / 24.0) - 229.17;
|
|
END_IF
|
|
|
|
HandleErrors();
|
|
|
|
CASE _iState OF
|
|
0: // Idle
|
|
// Start in normal mode
|
|
IF (xEnable OR xStartBalancing) AND xAllModulesInAutoMode AND xRepairSwitchOk AND (NOT _xErrorInternal) THEN
|
|
_xEnable := TRUE;
|
|
|
|
CASE eOperationMode OF
|
|
// Automatic mode (local or remote)
|
|
E_STRING_OPERATING_MODE.AUTOMATIC:
|
|
_iState := 5;
|
|
|
|
// Balancing mode
|
|
E_STRING_OPERATING_MODE.BALANCING:
|
|
_xStartBalancing := TRUE;
|
|
_xReleaseLimitErrorsInternal := FALSE;
|
|
_xEnable := FALSE;
|
|
_iState := 7;
|
|
|
|
// Safety check mode
|
|
E_STRING_OPERATING_MODE.SAFETY_CHECK:
|
|
_iState := 1;
|
|
|
|
// Precharge mode
|
|
E_STRING_OPERATING_MODE.PRECHARGE:
|
|
_iState := 1;
|
|
END_CASE
|
|
END_IF
|
|
|
|
IF _xErrorInternal THEN
|
|
_iState := 1000;
|
|
END_IF
|
|
|
|
|
|
1: // Wait for ready in safety check mode
|
|
IF _xAllModulesReady THEN
|
|
_xReleaseLimitErrorsInternal := TRUE;
|
|
_iState := 10;
|
|
END_IF
|
|
|
|
IF (NOT xEnable) THEN
|
|
_xEnable := FALSE;
|
|
_iState := 0;
|
|
END_IF
|
|
|
|
IF _xErrorInternal THEN
|
|
_iState := 1000;
|
|
END_IF
|
|
|
|
5: // Wait for all modules to be ready in normal mode
|
|
IF _xAllModulesReady AND _xBalanceOk THEN
|
|
_xReleaseLimitErrorsInternal := TRUE;
|
|
_iState := 10;
|
|
END_IF
|
|
|
|
IF (NOT xEnable) THEN
|
|
_xEnable := FALSE;
|
|
_iState := 0;
|
|
END_IF
|
|
|
|
IF _xErrorInternal THEN
|
|
_iState := 1000;
|
|
END_IF
|
|
|
|
7: // Wait for all modules to be ready in balancing mode
|
|
IF _xAllModulesReady THEN
|
|
_iState := 50;
|
|
END_IF
|
|
|
|
IF (NOT xStartBalancing) THEN
|
|
_xStartBalancing := FALSE;
|
|
//eStatus := E_COMPONENT_STATUS.OFF;
|
|
_iState := 0;
|
|
END_IF
|
|
|
|
IF _xErrorInternal THEN
|
|
_iState := 1000;
|
|
END_IF
|
|
|
|
|
|
10: // Reset safety from sensors
|
|
xResetSafety := FALSE;
|
|
_tonSafetyOkTimeout.IN := TRUE;
|
|
_iState := 15;
|
|
|
|
15: // Wait for Safety to be ok
|
|
xResetSafety := _fbSafetyResetImpulseGen.xOut;
|
|
IF xSafetyIntlksOk THEN
|
|
xResetSafety := FALSE;
|
|
_tonSafetyOkTimeout.IN := FALSE;
|
|
xCloseDCCB := TRUE;
|
|
_tonErrorDCCBNotClosed.IN := TRUE;
|
|
_iState := 20;
|
|
END_IF
|
|
|
|
IF (NOT xEnable) THEN
|
|
_tonSafetyOkTimeout.IN := FALSE;
|
|
xResetSafety := FALSE;
|
|
_xEnable := FALSE;
|
|
_iState := 40;
|
|
END_IF
|
|
|
|
IF _tonSafetyOkTimeout.Q THEN
|
|
_tonSafetyOkTimeout.IN := FALSE;
|
|
xResetSafety := FALSE;
|
|
xCloseDCCB := TRUE;
|
|
xError := TRUE;
|
|
xReady := FALSE;
|
|
IF (NOT _fbSafetyIntlkTimeoutAlarm.bRaised) THEN
|
|
_fbSafetyIntlkTimeoutAlarm.Raise(0);
|
|
END_IF
|
|
_iState := 1000;
|
|
END_IF
|
|
|
|
IF _xErrorInternal THEN
|
|
_iState := 1000;
|
|
END_IF
|
|
|
|
20: // Check if DC relais closed and safety is ok
|
|
IF (NOT xDCCBOpen) THEN
|
|
_xReleaseSafetyIntlkErrors := TRUE;
|
|
_tonErrorDCCBNotClosed.IN := FALSE;
|
|
|
|
CASE eOperationMode OF
|
|
E_STRING_OPERATING_MODE.AUTOMATIC:
|
|
_rPowerInverterInternal := rPowerInverter;
|
|
_xEnableInverter := TRUE;
|
|
_iState := 21;
|
|
|
|
E_STRING_OPERATING_MODE.SAFETY_CHECK:
|
|
_rPowerInverterInternal := 0.0;
|
|
_xEnableInverter := TRUE;
|
|
_iState := 21;
|
|
|
|
E_STRING_OPERATING_MODE.PRECHARGE:
|
|
_rPowerInverterInternal := 0.0;
|
|
_xEnableInverter := FALSE;
|
|
_iState := 29;
|
|
|
|
// Balancing mode should never reach this point!
|
|
// Its just here for testing
|
|
E_STRING_OPERATING_MODE.BALANCING:
|
|
_rPowerInverterInternal := 0.0;
|
|
_xEnableInverter := FALSE;
|
|
_iState := 50;
|
|
END_CASE
|
|
END_IF
|
|
|
|
IF _tonErrorDCCBNotClosed.Q THEN
|
|
_xEnable := FALSE;
|
|
xCloseDCCB := FALSE;
|
|
_tonErrorDCCBNotClosed.IN := FALSE;
|
|
xError := TRUE;
|
|
xReady := FALSE;
|
|
IF (NOT _fbDCMainSwitchNotClosed.bRaised) THEN
|
|
_fbDCMainSwitchNotClosed.Raise(0);
|
|
END_IF
|
|
_iState := 1000;
|
|
END_IF
|
|
|
|
IF (NOT xEnable) THEN
|
|
_tonSafetyOkTimeout.IN := FALSE;
|
|
_xEnable := FALSE;
|
|
//eStatus := E_COMPONENT_STATUS.SHUTDOWN;
|
|
_iState := 40;
|
|
END_IF
|
|
|
|
IF _xErrorInternal THEN
|
|
_iState := 1000;
|
|
END_IF
|
|
|
|
21: // Wait some time for inverter dc bus voltage settling
|
|
_fbTONDCSettlingTime(IN := TRUE);
|
|
IF _fbTONDCSettlingTime.Q THEN
|
|
_fbTONDCSettlingTime(IN := FALSE);
|
|
_xEnableInverter := TRUE;
|
|
_iState := 22;
|
|
END_IF
|
|
|
|
22: // Wait for inverter to be ready
|
|
_tonInverterStartupTimeout(IN := TRUE);
|
|
IF _fbInverter.xActive AND (NOT _fbInverter.xError) THEN
|
|
CASE eOperationMode OF
|
|
E_STRING_OPERATING_MODE.SAFETY_CHECK:
|
|
_iState := 29;
|
|
ELSE
|
|
_iState := 30;
|
|
END_CASE
|
|
xReady := TRUE;
|
|
_tonInverterStartupTimeout(IN := FALSE);
|
|
END_IF
|
|
|
|
IF (NOT xEnable) OR (NOT _xAllModulesReady) THEN
|
|
_xEnableInverter := FALSE;
|
|
_rPowerInverterInternal := 0.0;
|
|
_xEnable := FALSE;
|
|
_iState := 31;
|
|
_tonInverterStartupTimeout(IN := FALSE);
|
|
END_IF
|
|
|
|
|
|
// Inverter error or timeout for startup
|
|
IF _fbInverter.xError OR (NOT xRepairSwitchOk) OR _tonInverterStartupTimeout.Q THEN // _tonInverterStartupTimeout.Q
|
|
// Shutdown beacause of inverter startup timeout
|
|
IF _tonInverterStartupTimeout.Q AND (NOT _fbInverterStartupTimeoutAlarm.bRaised) THEN
|
|
_fbInverterStartupTimeoutAlarm.Raise(0);
|
|
END_IF
|
|
|
|
_iState := 1000;
|
|
_xEnableInverter := FALSE;
|
|
xError := TRUE;
|
|
_xErrorInverter := TRUE;
|
|
_xEnable := FALSE;
|
|
_tonInverterStartupTimeout(IN := FALSE);
|
|
END_IF
|
|
|
|
29: // Ready in safety check mode
|
|
IF (NOT xEnable) THEN
|
|
_xEnable := FALSE;
|
|
_xReleaseLimitErrorsInternal := FALSE;
|
|
_iState := 31;
|
|
END_IF
|
|
|
|
IF _xErrorInternal THEN
|
|
_iState := 1000;
|
|
END_IF
|
|
|
|
30: // All modules ready
|
|
// !!! ATTENTION !!!
|
|
// BMS HAS TO SHUT DOWN THE INVERTER BEFORE DISSABLING THE STRING
|
|
// OTHERWISE THE DC CIRCUIT BREAKERS WILL OPEN WHILE THE INVERTER IS STILL ACTIVE
|
|
// THIS CAN DAMAGE THE INVERTER
|
|
IF rPowerInverter > DINT_TO_REAL(GVL_CONFIG.diMaxStringDischargePower) THEN
|
|
// Limit discharge power (> because discharging is a positive number)
|
|
_rPowerInverterInternal := DINT_TO_REAL(GVL_CONFIG.diMaxStringDischargePower);
|
|
ELSIF rPowerInverter < DINT_TO_REAL(GVL_CONFIG.diMaxStringChargingPower) THEN
|
|
// Limit charging power (< because charging is a negative number)
|
|
_rPowerInverterInternal := DINT_TO_REAL(GVL_CONFIG.diMaxStringChargingPower);
|
|
ELSE
|
|
// Power command within range
|
|
_rPowerInverterInternal := rPowerInverter;
|
|
END_IF
|
|
|
|
// Shutdown
|
|
IF (NOT xEnable) THEN
|
|
_xEnable := FALSE;
|
|
_xReleaseLimitErrorsInternal := FALSE;
|
|
IF GVL_CONFIG.xShutdownDischargeWithInverter THEN
|
|
_rPowerInverterInternal := GVL_CONFIG.rAbsShutdownDischargePower;
|
|
_iState := 31;
|
|
ELSE
|
|
_rPowerInverterInternal := 0.0;
|
|
_xEnableInverter := FALSE;
|
|
_iState := 40;
|
|
END_IF
|
|
|
|
ELSIF (NOT _xAllModulesReady) OR (NOT _xBalanceOk) OR (NOT xSafetyIntlksOk) OR (NOT xRepairSwitchOk) OR (_xErrorInternal) THEN
|
|
xError := TRUE;
|
|
_xReleaseLimitErrorsInternal := FALSE;
|
|
_xEnable := FALSE;
|
|
_rPowerInverterInternal := 0.0;
|
|
_xEnableInverter := FALSE;
|
|
_iState := 1000;
|
|
END_IF
|
|
|
|
31: // Wait for String to be in in shutdown discharge mode
|
|
IF _xAllModulesInShutdownDischargeMode THEN
|
|
_iState := 32;
|
|
END_IF
|
|
|
|
IF _xErrorInternal THEN
|
|
_rPowerInverterInternal := 0.0;
|
|
_xEnableInverter := FALSE;
|
|
_iState := 40;
|
|
END_IF
|
|
|
|
32: // Shutdown discharge mode
|
|
IF xShutdownDischargeAllowed AND (NOT xErrorShutdown) AND GVL_CONFIG.xShutdownDischargeWithInverter AND xSafetyIntlksOk AND (stInverterData.rActDCVoltage > 620.0) THEN
|
|
_rPowerInverterInternal := GVL_CONFIG.rAbsShutdownDischargePower;
|
|
ELSE
|
|
// Send shutdown message
|
|
IF NOT xShutdownDischargeAllowed THEN
|
|
_fbSDUnitThreshold.Send(0);
|
|
END_IF
|
|
|
|
IF (stInverterData.rActDCVoltage < 620.0) THEN
|
|
_fbSDDCLevel.Send(0);
|
|
END_IF
|
|
|
|
_rPowerInverterInternal := 0.0;
|
|
_xEnableInverter := FALSE;
|
|
_iState := 40;
|
|
END_IF
|
|
|
|
// Restart on Enable or StartBalancing
|
|
IF xEnable OR xStartBalancing THEN
|
|
_rPowerInverterInternal := 0.0;
|
|
//_xEnableInverter := FALSE;
|
|
_iState := 0;
|
|
END_IF
|
|
|
|
IF _xErrorInternal THEN
|
|
_iState := 1000;
|
|
END_IF
|
|
|
|
40: // Wait for inverter to shut down
|
|
IF (NOT _fbInverter.xActive) THEN
|
|
_iState := 41;
|
|
END_IF
|
|
|
|
IF _xErrorInternal THEN
|
|
_iState := 1000;
|
|
END_IF
|
|
|
|
41: // Debug delay time for inverter shutdown
|
|
_tonInverterShutdownDelay(IN := TRUE);
|
|
|
|
IF _tonInverterShutdownDelay.Q THEN
|
|
_tonInverterShutdownDelay(IN := FALSE);
|
|
xCloseDCCB := FALSE;
|
|
_xReleaseSafetyIntlkErrors := FALSE;
|
|
//eStatus := E_COMPONENT_STATUS.OFF;
|
|
_iState := 0;
|
|
END_IF
|
|
|
|
50: // Wait for balancing of all units to be done
|
|
IF _xBalancingDone THEN
|
|
_xStartBalancing := FALSE;
|
|
_iState := 51;
|
|
END_IF
|
|
|
|
IF _xErrorInternal THEN
|
|
_iState := 1000;
|
|
END_IF
|
|
|
|
51: // Check if start balancing has been releases to avoid a restart
|
|
IF (NOT xStartBalancing) THEN
|
|
//eStatus := E_COMPONENT_STATUS.OFF;
|
|
_iState := 0;
|
|
END_IF
|
|
|
|
IF _xErrorInternal THEN
|
|
_iState := 1000;
|
|
END_IF
|
|
|
|
1000: // Error state
|
|
_xEnable := FALSE;
|
|
_xEnableInverter := FALSE;
|
|
_rPowerInverterInternal := 0.0;
|
|
xError := TRUE;
|
|
|
|
_xReleaseLimitErrorsInternal := FALSE;
|
|
_xReleaseSafetyIntlkErrors := FALSE;
|
|
|
|
// Reset timer
|
|
_tonErrorDCCBNotClosed(IN := FALSE);
|
|
|
|
//eStatus := E_COMPONENT_STATUS.ERROR;
|
|
|
|
_iState := 1005;
|
|
|
|
1005: // Wait for inverter to be off
|
|
_tonInverterShutdownError(IN := TRUE);
|
|
|
|
// If inverter is not shutting down, hard disconnect it
|
|
IF (NOT _fbInverter.xActive) OR _tonInverterShutdownError.Q THEN
|
|
_tonInverterShutdownError(IN := FALSE);
|
|
xCloseDCCB := FALSE;
|
|
_iState := 1010;
|
|
END_IF
|
|
|
|
|
|
|
|
1010: // Error idle state
|
|
// Leave error state only if modules are deactivated
|
|
IF (NOT xEnable) AND (NOT _xErrorInternal) THEN
|
|
xError := FALSE;
|
|
_xReleaseSafetyIntlkErrors := FALSE;
|
|
ClearAlarms();
|
|
//eStatus := E_COMPONENT_STATUS.OFF;
|
|
_iState := 0;
|
|
END_IF
|
|
END_CASE
|
|
|
|
// ===============================
|
|
// Handle status
|
|
// ===============================
|
|
// String off
|
|
IF xOff AND (NOT xError) THEN
|
|
eStatus := E_COMPONENT_STATUS.OFF;
|
|
END_IF
|
|
|
|
// String starting
|
|
IF _xEnable AND (NOT _xAllModulesReady) AND (NOT xError) THEN
|
|
eStatus := E_COMPONENT_STATUS.STARTING;
|
|
END_IF
|
|
|
|
// String on
|
|
IF _xAllModulesReady AND _fbInverter.xActive AND (NOT xError) THEN
|
|
IF _rPowerInverterInternal < 0.0 THEN
|
|
eStatus := E_COMPONENT_STATUS.CHARGING;
|
|
ELSIF _rPowerInverterInternal > 0.0 THEN
|
|
eStatus := E_COMPONENT_STATUS.DISCHARGING;
|
|
ELSE
|
|
eStatus := E_COMPONENT_STATUS.ON;
|
|
END_IF
|
|
END_IF
|
|
|
|
// String in shutdown
|
|
IF xInShutdownDischargeMode AND (NOT xError) THEN
|
|
eStatus := E_COMPONENT_STATUS.SHUTDOWN;
|
|
END_IF
|
|
|
|
// String in error state
|
|
IF xError THEN
|
|
eStatus := E_COMPONENT_STATUS.ERROR;
|
|
END_IF
|
|
|
|
|
|
// ===============================
|
|
// Calculate string voltage
|
|
// ===============================
|
|
rCurrentVoltage := _fbModule1.rCurrentVoltage + _fbModule2.rCurrentVoltage + _fbModule3.rCurrentVoltage;
|
|
stHMIInterface.rVoltage := stHMIInterface.rVoltage* 0.95 + rCurrentVoltage * 0.05;
|
|
|
|
// ===============================
|
|
// Copy inverter data to SCADA interface
|
|
// ===============================
|
|
stHMIInterface.stInverterData := stInverterData;
|
|
|
|
IF _xAllModulesReady AND _xBalanceOk AND ((_iState = 30) OR (_iState = 29)) THEN
|
|
xReady := TRUE;
|
|
ELSE
|
|
xReady := FALSE;
|
|
END_IF
|
|
|
|
// Reset inverter startup timeout alarm
|
|
IF _fbInverterStartupTimeoutAlarm.bRaised AND xConfirmAlarms THEN
|
|
_fbInverterStartupTimeoutAlarm.Clear(0, TRUE);
|
|
END_IF
|
|
|
|
// Reset safetyinterlock timeout alarm
|
|
IF _fbSafetyIntlkTimeoutAlarm.bRaised AND xConfirmAlarms THEN
|
|
_fbSafetyIntlkTimeoutAlarm.Clear(0, TRUE);
|
|
END_IF
|
|
|
|
// Copy status to hmi interface
|
|
stHMIInterface.eStatus := eStatus;
|
|
|
|
// Reset Safety
|
|
xResetSafetyDCCB := xResetSafety;
|
|
|
|
xCloseDCCB := TRUE;]]></ST>
|
|
</Implementation>
|
|
<Action Name="ClearAlarms" Id="{541a307f-e5d8-4588-8fd3-6f4bdf6a71dd}">
|
|
<Implementation>
|
|
<ST><![CDATA[IF _fbDCMainSwitchNotClosed.bRaised THEN
|
|
_fbDCMainSwitchNotClosed.Clear(0, FALSE);
|
|
END_IF]]></ST>
|
|
</Implementation>
|
|
</Action>
|
|
<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
|
|
VAR
|
|
_sTemp : STRING;
|
|
END_VAR
|
|
]]></Declaration>
|
|
<Implementation>
|
|
<ST><![CDATA[_sName := sName;
|
|
|
|
// Set names for modules
|
|
_fbModule1.Name := Concat(_sName, ' - Module 1');
|
|
_fbModule2.Name := Concat(_sName, ' - Module 2');
|
|
_fbModule3.Name := Concat(_sName, ' - Module 3');
|
|
|
|
// Create out of balance alarm
|
|
_fbModulesOutOfBalanceAlarm.CreateEx(stEventEntry := TC_EVENTS.BMSEvents.StringImbalance, bWithConfirmation := TRUE, 0);
|
|
_fbModulesOutOfBalanceAlarm.ipArguments.Clear().AddString(_sName);
|
|
|
|
// Create safetyinterlocks active alarm
|
|
_fbSafetyInterlocksNotOkAlarm.CreateEx(stEventEntry := TC_EVENTS.BMSEvents.SafetyIntlksActive, bWithConfirmation := FALSE, 0);
|
|
_fbSafetyInterlocksNotOkAlarm.ipArguments.Clear().AddString(_sName);
|
|
|
|
// Create inverter startup timeout alarm
|
|
_fbInverterStartupTimeoutAlarm.CreateEx(stEventEntry := TC_EVENTS.BMSEvents.InverterStartupTimeout, bWithConfirmation := TRUE, 0);
|
|
_fbInverterStartupTimeoutAlarm.ipArguments.Clear().AddString(_sName);
|
|
|
|
// Create DC Main Switch not closed alarm
|
|
_fbDCMainSwitchNotClosed.CreateEx(stEventEntry := TC_EVENTS.General.DCMainSwitchNotClosed, bWithConfirmation := FALSE, 0);
|
|
_fbDCMainSwitchNotClosed.ipArguments.Clear().AddString(_sName);
|
|
|
|
// EtherCAT communication lost alarm
|
|
_fbSCSConnLost.CreateEx(stEventEntry := TC_EVENTS.General.CommError, bWithConfirmation := TRUE, 0);
|
|
_sTemp := CONCAT(_sName, ' SCS');
|
|
_fbSCSConnLost.ipArguments.Clear().AddString(_sTemp);
|
|
|
|
// Safety interlock reset timeout alarm
|
|
_fbSafetyIntlkTimeoutAlarm.CreateEx(stEventEntry := TC_EVENTS.BMSEvents.SafetyIntlkTimeout, bWithConfirmation := TRUE, 0);
|
|
_fbSafetyIntlkTimeoutAlarm.ipArguments.Clear().AddString(_sName);
|
|
|
|
// Shutdown discharge messages
|
|
_fbSDDCLevel.CreateEx(TC_EVENTS.BMSEvents.SDDCVoltage, 0);
|
|
_fbSDDCLevel.ipArguments.Clear().AddString(_sName);
|
|
|
|
_fbSDUnitThreshold.CreateEx(TC_EVENTS.BMSEvents.SDUnitThreshhold, 0);
|
|
_fbSDUnitThreshold.ipArguments.Clear().AddString(_sName);
|
|
|
|
// isolation alarm creation
|
|
_fbIsolationAlarm.CreateEx(stEventEntry := TC_EVENTS.General.IsoError, bWithConfirmation := TRUE, 0);
|
|
_fbIsolationAlarm.ipArguments.Clear().AddString(_sName);]]></ST>
|
|
</Implementation>
|
|
</Method>
|
|
<Action Name="HandleErrors" Id="{97c046d3-715e-4533-b060-2e11c6ac9c9b}">
|
|
<Implementation>
|
|
<ST><![CDATA[// Reset internal error flag
|
|
_xErrorInternal := FALSE;
|
|
|
|
// ===============================
|
|
// Safety ComError Handling
|
|
// ===============================
|
|
IF xSafetyComError THEN
|
|
_xErrorInternal := TRUE;
|
|
END_IF
|
|
|
|
// ===============================
|
|
// EtherCAT connection lost error handling
|
|
// ===============================
|
|
IF (xECWcState <> 0) AND (NOT _fbSCSConnLost.bRaised) AND xReleaseErrors THEN
|
|
_fbSCSConnLost.Raise(0);
|
|
END_IF
|
|
|
|
IF (xECWcState = 0) AND _fbSCSConnLost.bRaised THEN
|
|
_fbSCSConnLost.Clear(0, FALSE);
|
|
END_IF
|
|
|
|
IF _fbSCSConnLost.eConfirmationState = TcEventConfirmationState.WaitForConfirmation AND xConfirmAlarms THEN
|
|
_fbSCSConnLost.Confirm(0);
|
|
END_IF
|
|
|
|
IF (xECWcState <> 0) THEN
|
|
_xErrorInternal := TRUE;
|
|
END_IF
|
|
|
|
|
|
// ===============================
|
|
// DC Main switch error handling
|
|
// ===============================
|
|
IF (NOT xRepairSwitchOk) AND (NOT _fbDCMainSwitchNotClosed.bRaised) AND xReleaseErrors THEN
|
|
_fbDCMainSwitchNotClosed.Raise(0);
|
|
END_IF
|
|
|
|
IF xRepairSwitchOk AND _fbDCMainSwitchNotClosed.bRaised THEN
|
|
_fbDCMainSwitchNotClosed.Clear(0, FALSE);
|
|
END_IF
|
|
|
|
IF (NOT xRepairSwitchOk) THEN
|
|
_xErrorInternal := TRUE;
|
|
END_IF
|
|
|
|
|
|
// ===============================
|
|
// ISO Error handling
|
|
// ===============================
|
|
// Mute iso error when inverter is enabled
|
|
_xIsoErrorActive := ((NOT xIsolationOKL1) OR (NOT xIsolationOKL2)) AND (NOT _fbInverter.xActive) AND (xDCCBOpen);
|
|
_fbTONIsoError(IN := _xIsoErrorActive, PT := GVL_CONFIG.timIsoErrorTimeout);
|
|
|
|
IF _fbTONIsoError.Q AND (NOT _fbIsolationAlarm.bRaised) AND xReleaseErrors THEN
|
|
_fbIsolationAlarm.Raise(0);
|
|
END_IF
|
|
|
|
IF (NOT _fbTONIsoError.Q) AND _fbIsolationAlarm.bRaised THEN
|
|
_fbIsolationAlarm.Clear(0, FALSE);
|
|
END_IF
|
|
|
|
IF _fbIsolationAlarm.eConfirmationState = TcEventConfirmationState.WaitForConfirmation AND xConfirmAlarms THEN
|
|
_fbIsolationAlarm.Confirm(0);
|
|
END_IF
|
|
|
|
IF _fbTONIsoError.Q THEN
|
|
_xIsoError := TRUE;
|
|
END_IF
|
|
|
|
IF xConfirmAlarms AND (NOT _fbTONIsoError.Q) THEN
|
|
_xIsoError := FALSE;
|
|
END_IF
|
|
|
|
IF _xIsoError THEN
|
|
_xErrorInternal := TRUE;
|
|
refuStringErrorsModbus.stBitmap.bIsolationError := 1;
|
|
END_IF
|
|
|
|
|
|
// ===============================
|
|
// Handle modules error state
|
|
// ===============================
|
|
IF _fbModule1.xError OR _fbModule2.xError OR _fbModule3.xError THEN
|
|
_xErrorInternal := TRUE;
|
|
END_IF
|
|
|
|
|
|
// ===============================
|
|
// Handle component safety interlocks ok
|
|
// ===============================
|
|
xSafetyIntlksComponentsOk := _fbModule1.xSafetyIntlksOk AND _fbModule2.xSafetyIntlksOk AND _fbModule3.xSafetyIntlksOk;
|
|
IF (NOT xSafetyIntlksComponentsOk) THEN
|
|
_xErrorInternal := TRUE;
|
|
END_IF
|
|
|
|
|
|
// ===============================
|
|
// Handle safety interlock alarm
|
|
// ===============================
|
|
IF (NOT xSafetyIntlksOk) AND (NOT _fbSafetyInterlocksNotOkAlarm.bRaised) AND xReleaseErrors AND _xReleaseSafetyIntlkErrors THEN
|
|
_fbSafetyInterlocksNotOkAlarm.Raise(0);
|
|
END_IF
|
|
|
|
IF (xSafetyIntlksOk OR (NOT xReleaseErrors) OR (NOT _xReleaseSafetyIntlkErrors)) AND _fbSafetyInterlocksNotOkAlarm.bRaised THEN
|
|
_fbSafetyInterlocksNotOkAlarm.Clear(0, TRUE);
|
|
END_IF
|
|
|
|
IF (NOT xSafetyIntlksOk) AND _xReleaseSafetyIntlkErrors THEN
|
|
_xErrorInternal := TRUE;
|
|
END_IF
|
|
|
|
|
|
// ===============================
|
|
// String balance check
|
|
// ===============================
|
|
// Reset balance ok flag
|
|
_xBalanceOk := TRUE;
|
|
|
|
// Test module 1 with module 2
|
|
IF ABS(_fbModule1.rCurrentVoltage - _fbModule2.rCurrentVoltage) > GVL_CONFIG.rMaxAbsDiffVoltageModulesInString THEN
|
|
_xBalanceOk := FALSE;
|
|
END_IF
|
|
|
|
// Test module 1 with module 3
|
|
IF ABS(_fbModule1.rCurrentVoltage - _fbModule3.rCurrentVoltage) > GVL_CONFIG.rMaxAbsDiffVoltageModulesInString THEN
|
|
_xBalanceOk := FALSE;
|
|
END_IF
|
|
|
|
// Test module 2 with module 3
|
|
IF ABS(_fbModule2.rCurrentVoltage - _fbModule3.rCurrentVoltage) > GVL_CONFIG.rMaxAbsDiffVoltageModulesInString THEN
|
|
_xBalanceOk := FALSE;
|
|
END_IF
|
|
|
|
// Release signal for balance not ok
|
|
_fbBalanceNotOkSignal(
|
|
xSignal:= NOT _xBalanceOk,
|
|
xRelease:= xEnable AND _xAllModulesReady,
|
|
timOnDelay:= T#10S,
|
|
timOffDelay:= T#10S,
|
|
xReleaseSignal=> );
|
|
|
|
// Signal an error if all units are ready and module is out of balance
|
|
IF _fbBalanceNotOkSignal.xReleaseSignal THEN
|
|
_xErrorInternal := TRUE;
|
|
END_IF
|
|
|
|
// Raise error
|
|
IF _fbBalanceNotOkSignal.xReleaseSignal AND (NOT _fbModulesOutOfBalanceAlarm.bRaised) AND xReleaseErrors THEN
|
|
_fbModulesOutOfBalanceAlarm.Raise(0);
|
|
END_IF
|
|
|
|
// Clear error
|
|
IF (NOT _fbBalanceNotOkSignal.xReleaseSignal) AND _fbModulesOutOfBalanceAlarm.bRaised AND xConfirmAlarms THEN
|
|
_fbModulesOutOfBalanceAlarm.Clear(0, FALSE);
|
|
END_IF
|
|
|
|
// Confirm error
|
|
IF _fbModulesOutOfBalanceAlarm.eConfirmationState = TcEventConfirmationState.WaitForConfirmation AND xConfirmAlarms THEN
|
|
_fbModulesOutOfBalanceAlarm.Confirm(0);
|
|
END_IF
|
|
|
|
|
|
// ===============================
|
|
// Handle inverter error
|
|
// ===============================
|
|
IF _fbInverter.xError THEN
|
|
_xErrorInternal := TRUE;
|
|
END_IF]]></ST>
|
|
</Implementation>
|
|
</Action>
|
|
<Property Name="Name" Id="{19fcb6d4-fd4b-49f9-9791-1e4c931b9e69}">
|
|
<Declaration><![CDATA[PROPERTY Name : String]]></Declaration>
|
|
<Get Name="Get" Id="{a4b6ba34-8ad9-46b1-939c-45cef957fd9a}">
|
|
<Declaration><![CDATA[VAR
|
|
END_VAR
|
|
]]></Declaration>
|
|
<Implementation>
|
|
<ST><![CDATA[Name := _sName;]]></ST>
|
|
</Implementation>
|
|
</Get>
|
|
<Set Name="Set" Id="{c32997c5-bac4-4ef0-bc87-edcbbb2e542f}">
|
|
<Declaration><![CDATA[VAR
|
|
END_VAR
|
|
]]></Declaration>
|
|
<Implementation>
|
|
<ST><![CDATA[_sName := Name;
|
|
|
|
// Set modules names
|
|
_fbModule1.Name := CONCAT(_sName, ' - Module 1');
|
|
_fbModule2.Name := CONCAT(_sName, ' - Module 2');
|
|
_fbModule3.Name := CONCAT(_sName, ' - Module 3');
|
|
|
|
// Set inverter Name
|
|
_fbInverter.Name := _sName;
|
|
|
|
// Create alarm messages
|
|
_fbModulesOutOfBalanceAlarm.ipArguments.Clear().AddString(_sName);
|
|
_fbSafetyInterlocksNotOkAlarm.ipArguments.Clear().AddString(_sName);
|
|
_fbSafetyIntlkTimeoutAlarm.ipArguments.Clear().AddString(_sName);]]></ST>
|
|
</Implementation>
|
|
</Set>
|
|
</Property>
|
|
</POU>
|
|
</TcPlcObject> |