FUNCTION_BLOCK RA_CIP_ELECTRICAL_ENERGY_OBJ
(*=====================================================================================================================================
	[UDFB Name]					:RA_CIP_ELECTRICAL_ENERGY_OBJECT (v7)     
	[Category]					:Communication
	[Description]				:Read the CIP Electrical Energy Object Attributes from a compatible device using Explicit Messaging
	[Author]					:Rockwell Automation
	[Created using CCW version]	:7.0
	[FeedBack]					:RASampleCode@ra.rockwell.com
	[Revison History]			:2014-December - Original Release for Version 7
	[Notes]						:Tested at release with E300 and PowerMonitor 5000

 =====================================================================================================================================*)

FBENO := FBEN;
(*-------- Initialize --------*)
FBEN_RTRIG(FBEN);
IF (__SYSVA_FIRST_SCAN OR FBEN_RTRIG.Q) THEN
	MSGProdName_EN					:= TRUE;
	MSGObjRead_EN					:= FALSE;
	ProdNameCtrlCfg.TriggerType		:= 5000;
	
	IF UpdateRate_ms < 1000 THEN 
   		ObjReadCtrlCfg.TriggerType 	:= 1000; (*Triggers message every 1000 ms while MSGObjRead_EN is true*)
	ELSE
		ObjReadCtrlCfg.TriggerType 	:= ANY_TO_UDINT(UpdateRate_ms);
	END_IF;
	
	ProdNameTargetCfg.Path			:= '4,'+ IPAddress;
	ProdNameTargetCfg.CipConnMode	:= 0;    (*0-unconnected, 1-Class 3*)
	ProdNameTargetCfg.UcmmTimeout	:= 250;  (*Unconnected message time out, Set to 0 means 3000ms, range 250-10000*)
	ProdNameTargetCfg.ConnMsgTimeout:= 800;  (*Class3 time out, Set to 0 means 3000ms, range 800-10000*)
	ProdNameTargetCfg.ConnClose		:= FALSE;(*Don't close the connection upon message completion*)
	ProdNameAppCfg.Service			:= 14;   (*Service code 0Eh for Get Single Attribute*)
	ProdNameAppCfg.Class			:= 1;    (*Class code 01h for Identity Object*)
	ProdNameAppCfg.Instance			:= 1;    (*Instance 1*)
	ProdNameAppCfg.Attribute		:= 7;    (*Attribute 7 for Product Name*)
	ObjReadTargetCfg.Path			:= '4,'+ IPAddress;
	ObjReadTargetCfg.CipConnMode	:= 0;    (*0-unconnected, 1-Class 3*)
	ObjReadTargetCfg.UcmmTimeout	:= 250;  (*Unconnected message time out, Set to 0 means 3000ms, range 250-10000*)
	ObjReadTargetCfg.ConnMsgTimeout	:= 800;  (*Class3 time out, Set to 0 means 3000ms, range 800-10000*)
	ObjReadTargetCfg.ConnClose		:= FALSE;(*Don't close the connection upon message completion*)
	ObjReadAppCfg.Service			:= 1;    (*Service code 01h for Get Attributes All*)
	ObjReadAppCfg.Class				:= 79;   (*Class code 4Fh for Electrical Energy Object*)
	ObjReadAppCfg.Instance			:= 1;    (*Instance 1*)
	ObjReadAppCfg.Attribute			:= 0;    (*Attribute 0*)
	CIPErrorStatus					:= NoErrorStatus;
	ProductName[1]					:= '';
	EEObjAttributes					:= ZeroedAttributes;
	
	FOR i := 0 TO 40 DO
		EnergyINTArray[i]:= 0;
	END_FOR;
	
	FOR i := 0 TO 30 DO
		MeteringREALArray[i]:= 0.0;
	END_FOR;
	
END_IF;

FBEN_FTRIG(FBEN);
IF FBEN_FTRIG.Q THEN
	CIPErrorStatus	:= NoErrorStatus;
	ProductName[1]	:= '';
	EEObjAttributes	:= ZeroedAttributes;
		
	FOR i := 0 TO 40 DO
		EnergyINTArray[i]:= 0;
	END_FOR;
	
	FOR i := 0 TO 30 DO
		MeteringREALArray[i]:= 0.0;
	END_FOR;
	
END_IF;

(*-------- Main Routine --------*)
IF FBEN THEN
	MSGProdName_Q_RTRIG(MSGProdName.Q);
	MSGObjRead_Q_RTRIG(MSGObjRead.Q);
		
	IF MSGProdName_Q_RTRIG.Q THEN
		CIPErrorStatus	:= MSGProdName.Status;
		ProdName_COP(TRUE,ProdNameResData,0,ProductName,0,1,FALSE);
		MSGProdName_EN	:= FALSE;
		MSGObjRead_EN	:= TRUE;
	END_IF;
		
	IF MSGObjRead_Q_RTRIG.Q THEN
		CIPErrorStatus	:= MSGObjRead.Status;
		INT_COP(TRUE,ObjReadResData,0,EnergyINTArray,0,40,TRUE);
		REAL_COP(TRUE,ObjReadResData,80,MeteringREALArray,0,31,TRUE);
		Phase_COP(TRUE,ObjReadResData,204,EnergyINTArray,40,1,TRUE);
		EEObjAttributes.RealEnergyConsumedOdometer		:= ANY_TO_LREAL(EnergyINTArray[4])*1.0E+9 +
														ANY_TO_LREAL(EnergyINTArray[3])*1.0E+6 +
														ANY_TO_LREAL(EnergyINTArray[2])*1.0E+3 +
														ANY_TO_LREAL(EnergyINTArray[1]) +
														ANY_TO_LREAL(EnergyINTArray[0])*1.0E-3;
		EEObjAttributes.RealEnergyGeneratedOdometer		:= ANY_TO_LREAL(EnergyINTArray[9])*1.0E+9 +
														ANY_TO_LREAL(EnergyINTArray[8])*1.0E+6 +
														ANY_TO_LREAL(EnergyINTArray[7])*1.0E+3 +
														ANY_TO_LREAL(EnergyINTArray[6]) +
														ANY_TO_LREAL(EnergyINTArray[5])*1.0E-3;
		EEObjAttributes.RealEnergyNetOdometer			:= ANY_TO_LREAL(EnergyINTArray[14])*1.0E+9 +
														ANY_TO_LREAL(EnergyINTArray[13])*1.0E+6 +
														ANY_TO_LREAL(EnergyINTArray[12])*1.0E+3 +
														ANY_TO_LREAL(EnergyINTArray[11]) +
														ANY_TO_LREAL(EnergyINTArray[10])*1.0E-3;
		EEObjAttributes.ReactiveEnergyConsumedOdometer	:= ANY_TO_LREAL(EnergyINTArray[19])*1.0E+9 +
														ANY_TO_LREAL(EnergyINTArray[18])*1.0E+6 +
														ANY_TO_LREAL(EnergyINTArray[17])*1.0E+3 +
														ANY_TO_LREAL(EnergyINTArray[16]) +
														ANY_TO_LREAL(EnergyINTArray[15])*1.0E-3;
		EEObjAttributes.ReactiveEnergyGeneratedOdometer	:= ANY_TO_LREAL(EnergyINTArray[24])*1.0E+9 +
														ANY_TO_LREAL(EnergyINTArray[23])*1.0E+6 +
														ANY_TO_LREAL(EnergyINTArray[22])*1.0E+3 +
														ANY_TO_LREAL(EnergyINTArray[21]) +
														ANY_TO_LREAL(EnergyINTArray[20])*1.0E-3;
		EEObjAttributes.ReactiveEnergyNetOdometer		:= ANY_TO_LREAL(EnergyINTArray[29])*1.0E+9 +
														ANY_TO_LREAL(EnergyINTArray[28])*1.0E+6 +
														ANY_TO_LREAL(EnergyINTArray[27])*1.0E+3 +
														ANY_TO_LREAL(EnergyINTArray[26]) +
														ANY_TO_LREAL(EnergyINTArray[25])*1.0E-3;
		EEObjAttributes.ApparentEnergyOdometer			:= ANY_TO_LREAL(EnergyINTArray[34])*1.0E+9 +
														ANY_TO_LREAL(EnergyINTArray[33])*1.0E+6 +
														ANY_TO_LREAL(EnergyINTArray[32])*1.0E+3 +
														ANY_TO_LREAL(EnergyINTArray[31]) +
														ANY_TO_LREAL(EnergyINTArray[30])*1.0E-3;
		EEObjAttributes.KiloampereHoursOdometer			:= ANY_TO_LREAL(EnergyINTArray[39])*1.0E+9 +
														ANY_TO_LREAL(EnergyINTArray[38])*1.0E+6 +
														ANY_TO_LREAL(EnergyINTArray[37])*1.0E+3 +
														ANY_TO_LREAL(EnergyINTArray[36]) +
														ANY_TO_LREAL(EnergyINTArray[35])*1.0E-3;
		EEObjAttributes.LineFrequency					:= MeteringREALArray[0];
		EEObjAttributes.L1Current						:= MeteringREALArray[1];
		EEObjAttributes.L2Current						:= MeteringREALArray[2];
		EEObjAttributes.L3Current						:= MeteringREALArray[3];
		EEObjAttributes.AverageCurrent					:= MeteringREALArray[4];
		EEObjAttributes.PercentCurrentUnbalance			:= MeteringREALArray[5];
		EEObjAttributes.L1NVoltage						:= MeteringREALArray[6];
		EEObjAttributes.L2NVoltage						:= MeteringREALArray[7];
		EEObjAttributes.L3NVoltage						:= MeteringREALArray[8];
		EEObjAttributes.AverageLNVoltage				:= MeteringREALArray[9];
		EEObjAttributes.L1L2Voltage						:= MeteringREALArray[10];
		EEObjAttributes.L2L3Voltage						:= MeteringREALArray[11];
		EEObjAttributes.L3L1Voltage						:= MeteringREALArray[12];
		EEObjAttributes.AverageLLVoltage				:= MeteringREALArray[13];
		EEObjAttributes.PercentVoltageUnbalance			:= MeteringREALArray[14];
		EEObjAttributes.L1RealPower						:= MeteringREALArray[15];
		EEObjAttributes.L2RealPower						:= MeteringREALArray[16];
		EEObjAttributes.L3RealPower						:= MeteringREALArray[17];
		EEObjAttributes.TotalRealPower					:= MeteringREALArray[18];
		EEObjAttributes.L1ReactivePower					:= MeteringREALArray[19];
		EEObjAttributes.L2ReactivePower					:= MeteringREALArray[20];
		EEObjAttributes.L3ReactivePower					:= MeteringREALArray[21];
		EEObjAttributes.TotalReactivePower				:= MeteringREALArray[22];
		EEObjAttributes.L1ApparentPower					:= MeteringREALArray[23];
		EEObjAttributes.L2ApparentPower					:= MeteringREALArray[24];
		EEObjAttributes.L3ApparentPower					:= MeteringREALArray[25];
		EEObjAttributes.TotalApparentPower				:= MeteringREALArray[26];
		EEObjAttributes.L1TruePowerFactor				:= MeteringREALArray[27];
		EEObjAttributes.L2TruePowerFactor				:= MeteringREALArray[28];
		EEObjAttributes.L3TruePowerFactor				:= MeteringREALArray[29];
		EEObjAttributes.ThreePhaseTruePowerFactor		:= MeteringREALArray[30];
		
		CASE EnergyINTArray[40] OF
			1: EEObjAttributes.PhaseRotation	:= 'ABC';
			2: EEObjAttributes.PhaseRotation	:= 'ACB';
		ELSE
			EEObjAttributes.PhaseRotation		:= 'None';
		END_CASE;
	
	END_IF;
	
	MSGProdName_Err_RTRIG(MSGProdName.Status.Error);
	MSGObjRead_Err_RTRIG(MSGObjRead.Status.Error);
	
	IF MSGProdName_Err_RTRIG.Q THEN
		CIPErrorStatus	:= MSGProdName.Status;
		ProductName[1]	:= '';
	END_IF;
	
	IF MSGObjRead_Err_RTRIG.Q THEN
		MSGProdName_EN	:= TRUE;
		MSGObjRead_EN	:= FALSE;
		CIPErrorStatus	:= MSGObjRead.Status;
		ProductName[1]	:= '';
		EEObjAttributes	:= ZeroedAttributes;
		
		FOR i := 0 TO 40 DO
			EnergyINTArray[i]:= 0;
		END_FOR;
		
		FOR i := 0 TO 30 DO
			MeteringREALArray[i]:= 0.0;
		END_FOR;
		
	END_IF;
	
ELSE
	MSGProdName_EN	:= FALSE;
	MSGObjRead_EN	:= FALSE;
	
END_IF;

MSGProdName(MSGProdName_EN, ProdNameCtrlCfg, ProdNameAppCfg, ProdNameTargetCfg,, 0, ProdNameResData);
MSGObjRead(MSGObjRead_EN, ObjReadCtrlCfg, ObjReadAppCfg, ObjReadTargetCfg,, 0, ObjReadResData);



END_FUNCTION_BLOCK