<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4026.8">
  <POU Name="FB_PowerMeter" Id="{9d4159f4-2d3f-4522-a770-c038a26d9d77}" SpecialFunc="None">
    <Declaration><![CDATA[FUNCTION_BLOCK FB_PowerMeter
VAR_INPUT
	xGetEnergyCounters : BOOL;
	// IP 75 -> Umrichter
	// IP 80 -> Hilfsenergie
	sIpAddress : STRING(80);
END_VAR
VAR_OUTPUT
	lrEnergyFromGrid : LREAL;
	lrEnergyIntoGrid : LREAL;
	
	xBusy : BOOL;
	xError : BOOL;
END_VAR
VAR
	_fbReadRegs : FB_MBReadRegs;
	_awWordArray : ARRAY[0..3] OF WORD;
	_awSwapped : ARRAY[0..3] OF WORD;
	_udiErrorId : UDINT;
	
	_fbGetEnergyCounters : R_TRIG;
	_xResetEnergyCounter : BOOL;
	
	_iState : INT := 0;
END_VAR
]]></Declaration>
    <Implementation>
      <ST><![CDATA[_fbGetEnergyCounters(CLK := xGetEnergyCounters);

IF _fbGetEnergyCounters.Q THEN
	_xResetEnergyCounter := TRUE;
END_IF

CASE _iState OF
	0: // Idle
		IF _xResetEnergyCounter THEN
			xBusy := TRUE;
			xError := FALSE;
			_xResetEnergyCounter := FALSE;
			_iState := 10;
		END_IF
		
	10: // Read energy from grid
		_fbReadRegs(
			sIPAddr:= sIpAddress, 
			nTCPPort:= 502, 
			nUnitID:= 16#FF, 
			nQuantity:= 4, 
			nMBAddr:= 8192,
			cbLength:= SIZEOF(_awWordArray), 
			pDestAddr:= ADR(_awWordArray), 
			bExecute:= TRUE, 
			tTimeout:= , 
			bBusy=> , 
			bError=> , 
			nErrId=> , 
			cbRead=> );
			
		IF (NOT _fbReadRegs.bBusy) AND (NOT _fbReadRegs.bError) THEN
			_fbReadRegs(bExecute := FALSE);
			SwapArray();
			MEMCPY(ADR(lrEnergyFromGrid), ADR(_awSwapped), 8);
			_iState := 20;
		END_IF
		
		IF _fbReadRegs.bError THEN
			xBusy := FALSE;
			xError := TRUE;
			_udiErrorId := _fbReadRegs.nErrId;
			lrEnergyFromGrid := 0;
			_fbReadRegs(bExecute := FALSE);
			_iState := 1000;
		END_IF
		
	20: // Read energy to grid
		_fbReadRegs(
			sIPAddr:= '192.168.42.75', 
			nTCPPort:= 502, 
			nUnitID:= 16#FF, 
			nQuantity:= 4, 
			nMBAddr:= 8196,
			cbLength:= SIZEOF(_awWordArray), 
			pDestAddr:= ADR(_awWordArray), 
			bExecute:= TRUE, 
			tTimeout:= , 
			bBusy=> , 
			bError=> , 
			nErrId=> , 
			cbRead=> );
			
		IF (NOT _fbReadRegs.bBusy) AND (NOT _fbReadRegs.bError) THEN
			_fbReadRegs(bExecute := FALSE);
			SwapArray();
			MEMCPY(ADR(lrEnergyIntoGrid), ADR(_awSwapped), 8);
			_iState := 0;
			xBusy := FALSE;
		END_IF
		
		IF _fbReadRegs.bError THEN
			xBusy := FALSE;
			xError := TRUE;
			_udiErrorId := _fbReadRegs.nErrId;
			lrEnergyIntoGrid := 0;
			_fbReadRegs(bExecute := FALSE);
			_iState := 0;
		END_IF
END_CASE]]></ST>
    </Implementation>
    <Action Name="SwapArray" Id="{96198008-b45e-42ee-9345-377fed90aab6}">
      <Implementation>
        <ST><![CDATA[_awSwapped[0] := _awWordArray[3];
_awSwapped[1] := _awWordArray[2];
_awSwapped[2] := _awWordArray[1];
_awSwapped[3] := _awWordArray[0];]]></ST>
      </Implementation>
    </Action>
  </POU>
</TcPlcObject>