﻿<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
  <POU Name="SystemStatus" Id="{8bfa3379-c222-0acf-2237-be0d95d0340d}" SpecialFunc="None">
    <Declaration><![CDATA[PROGRAM SystemStatus

VAR
    eState                 : E_State := E_State.Init;
    bError                 : BOOL;                   // error flag (indicator: error occured)
    hrErrorCode            : HRESULT;                // last error code
    hrGetValue             : HRESULT;
    diskTotalSpace			: LWORD; 				// in bytes
	diskFreeSpace			: LWORD;				// in bytes
	diskUsagePercent		: LREAL;				// disk utilization
    fbDiagRegister         : FB_IPCDiag_Register := (sNetId:=cNetId);
    fbDiagRead             : FB_IPCDiag_ReadParameter := (sNetId:=cNetId);
   	fbDiagReadPeriodic     : FB_IPCDiag_ReadParameterPeriodic := (tPeriod:= T#10S, sNetId:=cNetId, eParameterKey:=E_IPCDiag_ParameterKey.Disk_VolumeList_FreeSpace);
   	readCount				: UINT;
END_VAR
VAR CONSTANT
    cNetId : T_AmsNetID := ''; // local
END_VAR
]]></Declaration>
    <Implementation>
      <ST><![CDATA[CASE eState OF
	E_State.Init:
		IF NOT fbDiagRegister.bBusy THEN
			fbDiagRegister(bExecute:=TRUE);
		ELSE
			fbDiagRegister(bExecute:=FALSE, bError=>bError, hrErrorCode=>hrErrorCode);
		END_IF
		IF NOT fbDiagRegister.bBusy THEN
			IF fbDiagRegister.bError THEN
				eState := E_State.Error;
			ELSE
				eState := E_State.ReadOnce;
			END_IF
		END_IF
	
	E_State.ReadOnce:
    IF NOT fbDiagRead.bBusy THEN
        fbDiagRead(bExecute:= TRUE, eParameterKey:=E_IPCDiag_ParameterKey.Disk_VolumeList_TotelSize, fbRegister:=fbDiagRegister);    
    ELSE
        fbDiagRead(bExecute:= FALSE, fbRegister:=fbDiagRegister, bError=>bError, hrErrorCode=>hrErrorCode);
    END_IF
    IF NOT fbDiagRead.bBusy THEN
        IF fbDiagRead.bError THEN
            eState := E_State.Error;
        ELSE // get value
            hrGetValue := fbDiagRead.GetParameter(pBuffer:=ADR(diskTotalSpace), nBufferSize:=SIZEOF(diskTotalSpace));    
            IF FAILED(hrGetValue) THEN
                eState := E_State.Error;
            ELSE
                eState := E_State.ReadPeriodically;
            END_IF
        END_IF
    END_IF       

	
	E_State.ReadPeriodically:
    fbDiagReadPeriodic(bEnable:=TRUE, fbRegister:=fbDiagRegister,
                       bError=>bError, hrErrorCode=>hrErrorCode);
    IF fbDiagReadPeriodic.bValid THEN
        fbDiagReadPeriodic.GetParameter(pBuffer:=ADR(diskFreeSpace), nBufferSize:=SIZEOF(diskFreeSpace) );    
		readCount := readCount +1;
		diskUsagePercent := LWORD_TO_LREAL((diskTotalSpace - diskFreeSpace)) / LWORD_TO_LREAL(diskTotalSpace);
    END_IF
    IF fbDiagReadPeriodic.bError THEN
        eState := E_State.Error;
    END_IF    
	
	e_state.Error:
		eState := E_State.Init;

END_CASE
 ]]></ST>
    </Implementation>
  </POU>
</TcPlcObject>