
//========================================================================*/
//												Fill Warnings and Alarms												*/
//------------------------------------------------------------------------*/
//																																				*/
//   AUTHORs:        S.Leconte
//
//   DESIGN ISSUEs:  Filling Warnings and Alarms from database
//									 for 1 crate.
//
//   MODIF_HISTORY:	 21.07.2004 - First version - Sylvain LECONTE
//
//========================================================================*/

main()
{
DebugN("Started fill_Warn_Alarm script");
dpConnect("fill_Warn_Alarm", FALSE, "fill_Warn_Alarm.trigger:_original.._value");
}

void fill_Warn_Alarm(string dpe1, bool flag)
{

int i;
int iRST, crate, Channel, Channel_No;
bool ok;
string dpName;
// Load database into Send values
file paraDB;
string address, addressF, sParameter;
string path;
// Parameters for all values in one line of the file opened:
string MoPS, crate_name, channel_name, next_channel;
string systemName=getSystemName();
string datapoint;
string line;
dyn_string data, MoPS_dp, para_split, modChannels;
	//[sylvain]dyn_float sendTest, sendTestF;
float errorOpen;
// Values relevant for the changing of states
float value, loAlarm, loWarn, hiWarn, hiAlarm;
int NbChar;

//==========================================================
//GET IRST and CRATE values
//==========================================================

//Get the startimg time of the script and print it in the log console
DebugN(getCurrentTime(), "Start filling Warnings and Alarms ");

//Get the parameters for filling Alarms and Warnings
dpGet("fill_Warn_Alarm.parameters:_original.._value", sParameter);
para_split=strsplit(sParameter,"|");
DebugN("Load parameters :",sParameter);

//Split string and get status. The format of the parameters send is Crate|State|Channel1,Channel2,....,ChannelN
sscanf(para_split[1],"%d", crate);
sscanf(para_split[2],"%d", iRST);

//Get the channels to modify. Channel_No = 255 means modify all channels
if (para_split[3]=="all"){
  Channel_No = 255;
  DebugN("Channel_No :", Channel_No);
}
else {
  modChannels = strsplit(para_split[3],",");
}

//Fill warnings and alarms if and only if fill_Warn_Alarm.trigger:_original.._value==TRUE, otherwise deactivate the alarms  
if (flag)
{
//==========================================================
// OPEN DATABASE
//========================================================== 

//generate the crate name
sprintf(crate_name,"Crate%02d",crate);

//Open Database

//Open OFF file if iRST=0
if (iRST==0){
	DebugN("Loading OFF state...",crate);
	sprintf(path,"C:/SCT_DCS/Configs/Mops/Cnf_Crate%02d_OFF.txt",crate);
  paraDB = fopen(path,"r");   
}

//Open ON file if iRST=1
else if (iRST==1){
	DebugN("Loading ON state...",crate);
	sprintf(path,"C:/SCT_DCS/Configs/Mops/Cnf_Crate%02d_ON.txt",crate);
  paraDB = fopen(path,"r");   
}

//Open STB file if iRST=2
else if (iRST==2){
	DebugN("Loading STB state...",crate);
	sprintf(path,"C:/SCT_DCS/Configs/Mops/Cnf_Crate%02d_STBY.txt",crate);
  paraDB = fopen(path,"r");   
}

//==========================================================
// LOAD PARAMETERS
//==========================================================  

//Check for errors
  errorOpen = ferror(paraDB);
  if (errorOpen!=0) {
     DebugN("File "+ path +" did not open / correctly");
     }
     
//if no errors load the database
  else {       
     
     i=1;
     sprintf(next_channel,"Channel%02d",modChannels[i]);
        
		 while(feof(paraDB)==0){
		 
     // 1. GET VALUES:
               
         //Scan each line of the database file and store the values in temporary items
				 NbChar = fgets (line,300,paraDB);
					
				if(NbChar!=0){			//to avoid empty lines (needed to avoid errors if there is an empty lines)
         data=strsplit(line,"\t");
         sscanf(data[1], "%s", MoPS);

//==========================================================
// SET SEND VALUES TO DATAPOINTS FOR STATES ON/OFF/STB
//==========================================================  
               
               MoPS_dp=strsplit(MoPS,".");
                              
               if(MoPS_dp[1]==crate_name){
               	
               		//Test on the channel to load only the channel that we want...
               		if(channel_name != MoPS_dp[2]&&Channel_No!=255){
               			DebugN(channel_name, MoPS_dp[2]);
               			if(next_channel==channel_name){
               				channel_name = MoPS_dp[2];
               				i++;
               				sscanf(modChannels[i],"%d",Channel_No);
               				DebugN(modChannels[i]);
               				sprintf(next_channel,"Channel%02d",Channel_No);
               			}
               			else channel_name = MoPS_dp[2];
               		}
               		
               		if(next_channel==channel_name||Channel_No==255){
               		
               				//fill Warnings and Alarms...
               				switch(MoPS_dp[3]){
               				case "LVch_Vcc":
               				case "LVps_Vcc":
         	      			case "LVretVcc":
        			       	case "LVch_Icc":
        			       	case "LVch_Vdd":
      			         	case "LVps_Vdd":
           			    	case "LVretVdd":
              			 	case "LVch_Idd":
			               	case "LVchVCSV":
     			          	case "LVchVCSI":
         			      	case "LVchPINV":
        			       	case "LVchPINI":
             			  	case "MOch_Tm0":
   			            	case "MOch_Tm1":
       			        	case "HVchVolt":
          			     	case "HVchCurr":
    			           		sscanf(data[3],"%f",loAlarm);
         								sscanf(data[4],"%f", loWarn);
         								sscanf(data[5],"%f", hiWarn);
         								sscanf(data[6],"%f", hiAlarm);
         					
       			        		sprintf(datapoint,systemName+MoPS+".Recv");
												setAlerts(datapoint, loAlarm, loWarn, hiWarn, hiAlarm);
												//DebugN("Alarms and Warnings set for "+datapoint);
               	
           			    		break;
             			  	default:
              			 		break;
              		}
               	}
               }
              }
         								
   	} 									//[sylvain] end "while" 
	}											//[sylvain] end "else" 

//==========================================================
// CLOSE CNF FILE
//========================================================== 

	fclose(paraDB);               
	DebugN(getCurrentTime(), "Filling Alarms and Warnings finished");
}
else{
	//disable Warnings and Alarms
	DebugN("Disable Alarms and Warnings",crate);
	Channel = 0;
	sprintf(dpName,systemName+"Crate%02d.Channel%02d",crate,Channel);
	i=1;
  sscanf(modChannels[i],"%d",Channel_No);
  sprintf(next_channel,"Channel%02d",Channel_No);
	while(dpExists(dpName)){
	
		sprintf(channel_name,"Channel%02d",Channel);
		DebugN(channel_name, Channel, Channel_No, next_channel,modChannels[i]);
               		
	  if(next_channel==channel_name||Channel_No==255){
			
			if(Channel_No!=255){
				i++;
 	    	if(modChannels[i]!=""){
 	    		sscanf(modChannels[i],"%d",Channel_No);
 	    		sprintf(next_channel,"Channel%02d",Channel_No);
 	    	}
			}
			
			dpDeactivateAlert (dpName+".LVch_Vcc.Recv", ok);		
			if ( ! ok)
				DebugN("Failed to deactivate alarm on dpe: "+dpName+".LVch_Vcc");
			dpDeactivateAlert (dpName+".LVps_Vcc.Recv", ok);		
			if ( ! ok)
				DebugN("Failed to deactivate alarm on dpe: "+dpName+".LVps_Vcc");
			dpDeactivateAlert (dpName+".LVretVcc.Recv", ok);		
			if ( ! ok)
				DebugN("Failed to deactivate alarm on dpe: "+dpName+".LVretVcc");
			dpDeactivateAlert (dpName+".LVch_Icc.Recv", ok);		
			if ( ! ok)
				DebugN("Failed to deactivate alarm on dpe: "+dpName+".LVch_Icc");
			dpDeactivateAlert (dpName+".LVch_Vdd.Recv", ok);		
			if ( ! ok)
				DebugN("Failed to deactivate alarm on dpe: "+dpName+".LVch_Vdd");
			dpDeactivateAlert (dpName+".LVps_Vdd.Recv", ok);		
			if ( ! ok)
				DebugN("Failed to deactivate alarm on dpe: "+dpName+".LVps_Vdd");
			dpDeactivateAlert (dpName+".LVretVdd.Recv", ok);		
			if ( ! ok)
				DebugN("Failed to deactivate alarm on dpe: "+dpName+".LVretVdd");
			dpDeactivateAlert (dpName+".LVch_Idd.Recv", ok);		
			if ( ! ok)
				DebugN("Failed to deactivate alarm on dpe: "+dpName+".LVch_Idd");
			dpDeactivateAlert (dpName+".LVchVCSV.Recv", ok);		
			if ( ! ok)
				DebugN("Failed to deactivate alarm on dpe: "+dpName+".LVchVCSV");
			dpDeactivateAlert (dpName+".LVchVCSI.Recv", ok);		
			if ( ! ok)
				DebugN("Failed to deactivate alarm on dpe: "+dpName+".LVchVCSI");
			dpDeactivateAlert (dpName+".LVchPINV.Recv", ok);		
			if ( ! ok)
				DebugN("Failed to deactivate alarm on dpe: "+dpName+".LVchPINV");
			dpDeactivateAlert (dpName+".LVchPINI.Recv", ok);		
			if ( ! ok)
				DebugN("Failed to deactivate alarm on dpe: "+dpName+".LVchPINI");
			dpDeactivateAlert (dpName+".MOch_Tm0.Recv", ok);		
			if ( ! ok)
				DebugN("Failed to deactivate alarm on dpe: "+dpName+".MOch_Tm0");
			dpDeactivateAlert (dpName+".MOch_Tm1.Recv", ok);		
			if ( ! ok)
				DebugN("Failed to deactivate alarm on dpe: "+dpName+".MOch_Tm1");
			dpDeactivateAlert (dpName+".HVchVolt.Recv", ok);		
			if ( ! ok)
				DebugN("Failed to deactivate alarm on dpe: "+dpName+".HVchVolt");
			dpDeactivateAlert (dpName+".HVchCurr.Recv", ok);		
			if ( ! ok)
				DebugN("Failed to deactivate alarm on dpe: "+dpName+".HVchCurr");
			DebugN("Alarms deactivated on dpe "+dpName);
		}
		Channel++;
		sprintf(dpName,systemName+"Crate%02d.Channel%02d",crate,Channel);
	}
}
}

void setAlerts(string dpeName, float Fatal_low, float Warn_low,
                                float Warn_high, float Fatal_high)
{
	string prefix = dpeName+":_alert_hdl.";
	dyn_errClass err;
	int rc, type;
	bool ok;
	dyn_string rangeTexts   = makeDynString ("Data is fatal Low", "Data is warn. Low", "Data is Normal",
															"Data is warn. High", "Data is fatal High");
	dyn_string rangeClasses = makeDynString ("alert.", "warning.", "", "warning.", "alert.");

if ( !( (Fatal_low < Warn_low) && (Warn_low < Warn_high) && (Warn_high < Fatal_high) ) )
	{
	ok=FALSE;
	if(Fatal_low == Warn_low){
		Fatal_low-=0.1;
		ok=TRUE;
		DebugN("Err : Fatal_low = Warn_low","Fatal_low change to "+Fatal_low+" for "+dpeName);
	}
	if(Warn_high == Fatal_high){
		Fatal_high+=0.1;
		ok=TRUE;
		DebugN("Err : Warn_high = Fatal_high","Fatal_high change to "+Fatal_high+" for "+dpeName);
	}
	if (!ok) {
		DebugN("Error! Invalid limits for", dpeName, " : ", Fatal_low, Warn_low, Warn_high, Fatal_high);
		return; 
	}
	}
	
//	DebugN(dpeName, " : ", Fatal_low, Warn_low, Warn_high, Fatal_high);
	
	// check if the alarm already exists
	rc = dpGet (prefix+"._type", type);
	err = getLastError ();	
	if (rc | dynlen(err)) {
		DebugN("Failed to check whether alarm already exists for dpe: "+dpeName+" : "+rc);
		throwError (err);
		return;
	}

	// if it exists, deactivate the alarm handling (so we can change it)
	if (type != DPCONFIG_NONE) {
		
		//Acknoledge Alerts		
		dpSetWait(dpeName+":_alert_hdl.._ack", DPATTR_ACKTYPE_MULTIPLE);
		
		dpDeactivateAlert (dpeName, ok);		
		if ( ! ok) {
			DebugN("Failed to deactivate alarm on dpe: "+dpeName);
			return;
		}
	}
	
	// configure the alarm
	rc = dpSetWait (prefix+"._type", DPCONFIG_ALERT_NONBINARYSIGNAL, // equal to 13!

					prefix+"1._type", DPDETAIL_RANGETYPE_MINMAX, // equal to 4!
					prefix+"1._u_limit", Fatal_low,
					prefix+"1._l_incl", TRUE,
					prefix+"1._u_incl", FALSE,
					prefix+"1._text",  rangeTexts [1],
					prefix+"1._class", rangeClasses [1],

					prefix+"2._type", DPDETAIL_RANGETYPE_MINMAX,
					prefix+"2._l_limit", Fatal_low,
					prefix+"2._u_limit", Warn_low,
					prefix+"2._l_incl", TRUE,
					prefix+"2._u_incl", FALSE,
					prefix+"2._text", rangeTexts [2],
					prefix+"2._class", rangeClasses [2],

					prefix+"3._type", DPDETAIL_RANGETYPE_MINMAX,
					prefix+"3._l_limit", Warn_low,
					prefix+"3._u_limit", Warn_high,
					prefix+"3._l_incl", TRUE,
					prefix+"3._u_incl", FALSE,
					prefix+"3._text", rangeTexts [3],
					prefix+"3._class", rangeClasses [3],

					prefix+"4._type", DPDETAIL_RANGETYPE_MINMAX,
					prefix+"4._l_limit", Warn_high,
					prefix+"4._u_limit", Fatal_high,
					prefix+"4._l_incl", TRUE,
					prefix+"4._u_incl", FALSE,
					prefix+"4._text", rangeTexts [4],
					prefix+"4._class", rangeClasses [4],

					prefix+"5._type", DPDETAIL_RANGETYPE_MINMAX,
					prefix+"5._l_limit", Fatal_high,
					prefix+"5._l_incl", TRUE,
					prefix+"5._u_incl", FALSE,
					prefix+"5._text", rangeTexts [5],
					prefix+"5._class", rangeClasses [5],
					prefix+"._orig_hdl", TRUE);
			
	err = getLastError ();	
	if (rc | dynlen(err)) {
		DebugN("Failed to set alarm on dpe: "+dpeName+" : "+rc);
		throwError (err);
		return;
	}

	//activate the alarm handling
	dpActivateAlert (dpeName, ok);		
	if ( ! ok) {
		DebugN("Failed to activate alarm on dpe: "+dpeName);
		return;
	}
}
