PROGRAM Control
(* First Scan Variable Setting*)
IF (__SYSVA_FIRST_SCAN) THEN
	Shutdown_Time := __SYSVA_CYCLEDATE;
	Device_Status:= 'Startup';
	Restart_Command := FALSE;
	Restart_Allowed := FALSE;
	Run_Permissive := FALSE;
	Start_Permissive := FALSE;
END_IF;

IF Downhole_Tool_Enabled THEN
	(*Modbus Mapping*)
	DH_IntakeTemperature 				:= ANY_TO_REAL(Modbus_Read0[2]) / 10.0;
	DH_IntakePressure 					:= ANY_TO_REAL(Modbus_Read0[3]);
	DH_NumChannels						:= Modbus_Read0[10];
	DH_ToolVoltage						:= Modbus_Read0[11];
	DH_MaxIntakeTemperature_Startup		:= ANY_TO_REAL(Modbus_Read0[40]) / 10.0;
	DH_MaxIntakePressure_Startup		:= Modbus_Read0[41];
	DH_DownholeStatus_INT				:= Modbus_Read0[99];
	DH_Fluid_Level 						:= (DH_IntakePressure - 14.0) * (1.0 / 0.433);

	CASE Modbus_Read0[99] OF
		0: DH_DownholeStatus := 'OK';
		1: DH_DownholeStatus := 'Connecting';
		2: DH_DownholeStatus := 'Open Circuit';
		3: DH_DownholeStatus := 'Shorted';
		4: DH_DownholeStatus := 'Cannot Decode';
	ELSE
		DH_DownholeStatus := 'Error';
	END_CASE;

	DH_ToolType							:= Modbus_Read1000[5];
	DH_PSIRating						:= Modbus_Read1000[7] * 1000;
	DH_MaxIntakeTemperature_Forever		:= ANY_TO_REAL(Modbus_Read1000[8]) / 10.0;
	DH_MaxIntakePressure_Forever		:= Modbus_Read1000[9];
ELSE
	DH_DownholeStatus := 'Disabled';
	DH_Pressure_Shutdown_Enabled := FALSE;
	DH_Pressure_Startup_Enabled := FALSE;
	DH_Temp_Shutdown_Enabled := FALSE;
	DH_Temp_Startup_Enabled := FALSE;
END_IF;

(*IO Mapping*)
IF NOT Test_Mode THEN
	Start_Button := _IO_EM_DI_01;
	Auto_Mode := _IO_EM_DI_02;
	Hand_Mode := _IO_EM_DI_03;
	
	LinearScale_Pressure(13107.0, 65535.0, TubingPressure_EU_Min, TubingPressure_EU_Max, ANY_TO_REAL(_IO_EM_AI_00));
	TubingPressure_In := LinearScale_Pressure.EU_Out;
	
	VFD_Disabled := FALSE;
ELSE
	(* TEST MODE LOGIC *)
	VFD_Disabled := TRUE;
	
	VFD_DCBusVoltage := 675.0 + ANY_TO_REAL(RAND(10)) / 10.0;
	
	IF VFD_Start THEN
		VFD_CmdSpeed := VFD_SpeedRef;
		VFD_SpeedFdbk := VFD_SpeedRef;
		VFD_OutputCurrent := 30.0 + ANY_TO_REAL(RAND(10)) / 10.0;
	END_IF;
	
	IF VFD_Stop THEN
		VFD_CmdSpeed := 0.0;
		VFD_SpeedFdbk := 0.0;
		VFD_OutputCurrent := 0.0;
		VFD_OutputVoltage := 0.0;
		
	END_IF;
	
END_IF;

IF TubingPressure_Transducer_Enabled AND 
	VFD_Running AND 
	ANY_TO_DINT(Run_Time) > (TubingPressure_Alarm_Startup_Delay * 1000) THEN

	IF TubingPressure_In >= TubingPressure_Hi_SP THEN
		TubingPressure_Hi := TRUE;
		TubingPressure_Lo := FALSE;
	ELSIF TubingPressure_in <= TubingPressure_Lo_SP THEN
		TubingPressure_Hi := FALSE;
		TubingPressure_Lo := TRUE;
	ELSE
		TubingPressure_Hi := FALSE;
		TubingPressure_Lo := FALSE;
	END_IF;
	
	IF NOT TubingPressure_Hi AND NOT TubingPressure_Lo THEN
		TubingPressure_OK := TRUE;
		TubingPressure_OOT_Scans := 0;
		TubingPressure_OOT_Seconds := 0;
	ELSE
		TubingPressure_OOT_Scans := TubingPressure_OOT_Scans + 1;
		TubingPressure_OOT_Seconds := TubingPressure_OOT_Scans * ANY_TO_UDINT(__SYSVA_TCYCURRENT) / 1000;
	END_IF;
	
	IF TubingPressure_OOT_Seconds > TubingPressure_Alarm_Delay THEN
		TubingPressure_OK := FALSE;
	END_IF;
ELSE 
	TubingPressure_OK := TRUE;
END_IF;


(* Pressure should be above the startup pressure setpoint and temperature should be below the startup temp setpoint to begin*)
IF ((((DH_IntakePressure > DH_Pressure_Startup) AND DH_Pressure_Startup_Enabled) OR NOT DH_Pressure_Startup_Enabled) AND 
	(((DH_IntakeTemperature < DH_Temp_Startup) AND DH_Temp_Startup_Enabled) OR NOT DH_Temp_Startup_Enabled) AND 
	(Hand_Mode OR Auto_Mode OR Test_Mode) AND
	(NOT VFD_Fault)
	) THEN
	Start_Permissive := TRUE;
ELSE
	Start_Permissive := FALSE;
	Device_Status := 'Not ready to start';
END_IF;

(* Pressure should be be above the shutdown pressure and temperature should be below shutdown temp setpoint to continue to run *)
IF ((((DH_IntakePressure > DH_Pressure_Shutdown) AND DH_Pressure_Shutdown_Enabled) OR NOT DH_Pressure_Shutdown_Enabled) AND 
	(((DH_IntakeTemperature < DH_Temp_Shutdown) AND DH_Temp_Shutdown_Enabled) OR NOT DH_Temp_Shutdown_Enabled) AND 
	(Hand_Mode OR Auto_Mode OR Test_Mode)
	AND (NOT VFD_Fault)
	AND TubingPressure_OK
	) THEN
	Run_Permissive := TRUE;
ELSE
	Run_Permissive := FALSE;
END_IF;

IF (NOT Run_Permissive AND VFD_Running) THEN
	Device_Status := 'Lost Run Permissive';
	Shutdown_Time := __SYSVA_CYCLEDATE;
	VFD_Start := FALSE;
	VFD_Start := TRUE;
END_IF;

(*  Run only if commanded to start and start permissive is met or already running and not being told to stop *)
IF ((((Start_Button OR Start_Command OR (Restart_Allowed AND Restart_Command)) AND Start_Permissive) OR VFD_Running) AND 
	(NOT Stop_Command) AND Run_Permissive) THEN
	VFD_Running := TRUE;
	Restart_Command:= FALSE;
	Start_Command := FALSE;
	IF NOT Start_Time_Set THEN
		Start_Time := __SYSVA_CYCLEDATE;
		Start_Time_Set := TRUE;
	END_IF;
		
	
	IF VFD_Running THEN
		Device_Status := 'Running';
		Run_Time := __SYSVA_CYCLEDATE - Start_Time;
	END_IF;
ELSE
	VFD_Start := FALSE;
	VFD_Stop := TRUE;
END_IF;


(* If run permissive goes false, do not allow a restart for a specified amount of time *)
IF (Auto_Mode AND (NOT VFD_Fault) AND NOT VFD_Running AND Restart_Allowed) THEN
	IF (__SYSVA_CYCLEDATE - Shutdown_Time) > Downtime_Time_Parameter THEN 
		IF (NOT Restart_Command) THEN
			VFD_ClearFault := TRUE;
			Restart_Command := True;
		END_IF;
	ELSE
		(* Attempt to clear trip every 15 seconds *)
		(*IF NOT Downtime_Timer.Q AND TripStatus THEN
			Downtime_Timer(TRUE, Clear_Trip_Cycle);
		ELSE
			TripResetCmd := TRUE;
		END_IF;*)
		
		Restart_Command := FALSE;
		Time_Until_Startup := Downtime_Time_Parameter - (__SYSVA_CYCLEDATE - Shutdown_Time);
		Time_Until_Startup_String := ANY_TO_STRING(Time_Until_Startup);
		IF Auto_Mode THEN
			Device_Status := 'Waiting to attempt restart ' + Time_Until_Startup_String;
		END_IF;
		
	END_IF;
END_IF;

IF NOT Auto_Mode THEN
	Restart_Command := FALSE;
	Restart_Allowed := FALSE;
END_IF;

(* If the pump hasn't been started by the user, don't allow it to auto-restart *)
IF (Start_Command OR Start_Button) AND Start_Permissive THEN
	Restart_Allowed := TRUE;
END_IF;

IF Stop_Command THEN
	Restart_Allowed := FALSE;
	Device_Status := 'User Stopped';
END_IF;

IF NOT VFD_Running THEN
	Start_Time_Set := FALSE;
END_IF;


(* Start Permissive Status *)
IF DH_Pressure_Startup_Enabled THEN
	IF (DH_IntakePressure > DH_Pressure_Startup) THEN
		SP_Pressure := TRUE;
	ELSE
		SP_Pressure := FALSE;
	END_IF;
ELSE
	SP_Pressure := TRUE;
END_IF;

IF DH_Temp_Startup_Enabled THEN
	IF DH_IntakeTemperature < DH_Temp_Startup THEN
		SP_Temperature := TRUE;
	ELSE
		SP_Temperature := FALSE;
	END_IF;
ELSE
	SP_Temperature := TRUE;
END_IF;

IF Hand_Mode OR Auto_Mode OR Test_Mode THEN
	SP_Mode := TRUE;
ELSE
	SP_Mode := FALSE;
END_IF;

(* Run Permissive Status *)
IF DH_Pressure_Shutdown_Enabled THEN
	IF DH_IntakePressure > DH_Pressure_Shutdown THEN
		RP_Pressure := TRUE;
	ELSE
		RP_Pressure := FALSE;
	END_IF;
ELSE
	RP_Pressure := TRUE;
END_IF;

IF DH_Temp_Shutdown_Enabled THEN
	IF DH_IntakeTemperature < DH_Temp_Shutdown THEN
		RP_Temperature := TRUE;
	ELSE
		RP_Temperature := FALSE;
	END_IF;
ELSE
	RP_Temperature := TRUE;
END_IF;

IF Hand_Mode OR Auto_Mode OR Test_Mode THEN
	RP_Mode := TRUE;
ELSE	
	RP_Mode := FALSE;
END_IF;

RP_TubingPressure := TubingPressure_OK;



END_PROGRAM