// DDC control 
//123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456*/
//===================================-======================================*/
//                         DDC STATE & DATA CONTROL                         */
//-----------------------------------=--------------------------------------*/
// AUTHORs:        P.Ferrari & Heidi Sandaker
//
//   DESIGN ISSUEs:  Run state transitions
//
//   MODIF_HISTORY:  25.07.2003 - first version
//                   30.07.2003 - Preliminary - H. Sandaker
//                   26.11.2003 - midofications for Finite State Machine P.Ferrari
//                   12.01.2004 - change of groups , HS & PF
//                   23.02.2004 - adding alerts HS, AA
//                   20.07.2004 - inhibit ramp up during Env. Alarm  PWP
//									 30.07.2004 - set "State" datatpoint
//===================================-======================================*/

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


}

void changeState(string Text, bool Flag) 
{
int iState,crate,channel,timeout,entries;
string allChannels;
string sParameter;
int max,i;
dyn_string para_split,para_split1;
string FWA_param;
string systemName=getSystemName();
int OK, OK2;
int error = 0;

//Disable PVSS alerts:
//  dpSet("Alert.Stat:_online.._value", 0);
//  dpSet("Info.Name:_original.._value", "CS: Disabling PVSS alerts...");
//  DebugN("CS: Disabling PVSS alerts...");

//Get Values from DAQ
dpGet("changeState.parameters:_original.._value", sParameter);
para_split=strsplit(sParameter,"|");
//DebugN("sParameter", sParameter);

//Split string and get status. The format of the parameters send by DDC is Crate|Channel|State
 
sscanf(para_split[1],"%d", crate);
sscanf(para_split[2],"%s", allChannels);
sscanf(para_split[3],"%d", iState);
sscanf(para_split[4],"%d", timeout);

if(allChannels == "all")
  {
   //IV curve for all channels
   para_split1[1] = 255;
   }
   else
   {
   //sscanf(allChannels,"%d", channel);
   para_split1=strsplit(allChannels,",");
   }
   //get the lenght of the array contyaining the channels to be ramped up
   max=dynlen(para_split1);
   
 //DebugN("item count",max,para_split1[1],para_split1[2],para_split1[3],para_split1[4]);
 //DebugN("iState", iState,"crate",crate,"channel",channel);
 
if (Flag==1){
   //Change State
      //DebugN("state is OFF");
      sprintf(FWA_param, crate + "|" + iState + "|");
      dpSet("Info.Name:_original.._value", "CS: Setting PS channels to new state...");
      DebugN("CS: Setting PS channels to new state...");
      // looping on channels that have to be ramped on
      for(i=1;i<=max;i++)
      {
       PSset2(iState,para_split1[i],crate);
      //	if (OK==0) error++;
      //	else{
      //		if (para_split1[i]!=255) sprintf(FWA_param, FWA_param + para_split1[i]+",");
      //		else sprintf(FWA_param, FWA_param + "all");
      //	}
      //	DebugN(FWA_param);
	  		delay(0,3);
      }
      DebugN("Nb of Error : ",error);
      if (error == 0){
      	//sprintf(FWA_param, crate + "|" + iState + "|"+ allChannels);
      	DebugN("fill_Warn_Alarm.parameters : " + FWA_param);
      	//fill Warn and Alarms for the corresponding state
      	dpSet("fill_Warn_Alarm.parameters:_original.._value", FWA_param);
				dpSetWait(systemName+"fill_Warn_Alarm.trigger:_original.._value", TRUE);
			}
      //dpSet("Info.Name:_original.._value", "CS: Finished!");
   //Read();
  delay(3);
  dpSetWait("changeState.trigger:_original.._value", 0);
  
  //Enable PVSS alerts:
// dpSet("Alert.Stat:_online.._value", 1);
//  dpSet("Info.Name:_original.._value", "CS: Enabling PVSS alerts...");
//  DebugN("CS: Enabling PVSS alerts...");
  }
}


int PSset2(int iState, int channel, int crate)
{
dyn_errClass err;
int  i,j,ichan;
int set,channel1;
string datapoint,datapoint2;
int ack,OK,fatal;
string cooling_status,cooling_state,systemName;
int ChannelNo = 0;
string datapoint5;

   // Must not ramp up if environmental alarm in progress
   // (ramp down is still allowed)
   if (iState>0) {
      dpGet("Fatl.Numb:_original.._value",fatal);
      if(fatal!=0){
         dpSet("Info.Name:_original.._value", "CS: Request Denied due to Environment Alarm (code "+fatal+")");
         DebugN("CS: Request Denied due to Environment Alarm (code "+fatal+")");
         return;     
      }
   }
//same for SR Cooling
//   if (iState>0) {
//     systemName=getSystemName(40);
//     dpGet(systemName +"Cooling.State:_original.._value",cooling_state);  
//     dpGet(systemName +"Cooling.Status:_original.._value",cooling_status);        
//     if(cooling_state!="Ready"||cooling_status!="OK"){
 //        dpSet("Info.Name:_original.._value", "Set_State: Request Denied due to Cooling Alarm (code "+fatal+")");
//         DebugN("Set_State: Request Denied due to Cooling Alarm (code "+fatal+")");
//         return;     
//      }
//   }

 sprintf(datapoint,"Crate%02d.Controller.CCch_Set.Send:_original.._value",crate);
 sprintf(datapoint2,"Crate%02d.Controller.CCcf_Ack.Recv:_online.._value",crate);
// DebugN("datapoint",datapoint);
 if(channel==255){
 if(iState==1)
   {
   OK=0;
   channel = 194 | (( iState & 0x00ff )<<8);
   dpSetWait(datapoint,channel);
   dpGet(datapoint2,ack);
   while ((ack!=channel)&&(i<20))
     {
     delay(1,0);
     i=i+1;
     dpGet(datapoint2,ack);
     //DebugN("on hv ",i,ack,channel);
     }
   i=0;
   if( ack==channel) OK=1; 
   //DebugN("on hv",OK,ack); 
   // send back confirmation to DAQ
   if(OK==1) {
   		dpSetWait("changeState.response:_original.._value",0);
   		
   		//set State for all channels
      ChannelNo = 0;
      sprintf(datapoint5, "Crate%02d.Channel%02d", crate, ChannelNo);
      while(dpExists(datapoint5)){
         dpSet(datapoint5+".State:_original.._value",iState);
         ChannelNo++;
         sprintf(datapoint5, "Crate%02d.Channel%02d", crate, ChannelNo);
      }
      //set State for the crate
      sprintf(datapoint5,"Crate%02d.State:_original.._value",crate);
    	dpSet(datapoint5,iState);
    	return 1;
   }
   }
 if(iState==2)
   {
   OK=0;
   // ramp LV to STB1
   channel = 128 | (( iState & 0x00ff )<<8); 
   dpSetWait(datapoint,channel); 
      DebugN("Lv channel",channel);
   dpGet(datapoint2,ack);
   while ((ack!=channel)&&(i<20))
     {
     delay(1,0);
     i=i+1;
     dpGet(datapoint2,ack);
     DebugN("LV",ack);
     }
   i=0;
   if( ack==channel) OK=1;	
   // ramp HV to STB1
   channel = 192 | (( iState & 0x00ff )<<8);
   dpSetWait(datapoint,channel);
   DebugN("HV channel",channel);
   // check that Ewa has done the transition
   dpGet(datapoint2,ack);
   while ((ack!=channel)&&(i<20))
     {
     delay(1,0);
     i=i+1;
     dpGet(datapoint2,ack);
          DebugN("HV",ack);
     }
   i=0;
   if(ack==channel&&OK==1) OK=2;
    // send back confirmation to DAQ
   if(OK==2)
   dpSetWait("changeState.response:_original.._value",0);
   }
   if(iState==0)
   {
   channel = 255 | (( iState & 0x00ff )<<8);
   dpSetWait(datapoint,channel);
   dpGet(datapoint2,ack);
   while ((ack!=channel)&&(i<20))
     {
     delay(1,0);
     i=i+1;
     dpGet(datapoint2,ack);
     }
   i=0;
   if( ack==channel) OK=1; 
   // send back confirmation to DAQ
   if(OK==1){
    	dpSetWait("changeState.response:_original.._value",0);
    	
    	//set State for all channels
      ChannelNo = 0;
      sprintf(datapoint5, "Crate%02d.Channel%02d", crate, ChannelNo);
      while(dpExists(datapoint5)){
         dpSet(datapoint5+".State:_original.._value",iState);
         ChannelNo++;
         sprintf(datapoint5, "Crate%02d.Channel%02d", crate, ChannelNo);
      }
      //set State for the crate
    	sprintf(datapoint5,"Crate%02d.State:_original.._value",crate);
    	dpSet(datapoint5,iState);
    	return 1;
   }
   }
 if(iState==4)
   {
   OK=0;  
   // ramp the LV's from STB to ON leave HV to STB
   channel = 130 | (( 1 & 0x00ff )<<8);
   dpSetWait(datapoint,channel);
   // check that Ewa has done the transition
     dpGet(datapoint2,ack);
   while ((ack!=channel)&&(i<20))
     {
     delay(1,0);
     i=i+1;
     dpGet(datapoint2,ack);
     DebugN("LV2",ack);
     }
   if(ack==channel) OK=1;
   i=0;  
   if(OK==1)
   dpSetWait("changeState.response:_original.._value",0);
  } 
 if(iState==5)
   {
     // ramp dwon the LV's from ON to STB and HV to STB
   iState=2;
   OK=0;
   // ramp down LV's
   channel = 193 | (( iState & 0x00ff )<<8);
   dpSetWait(datapoint,channel);
   dpGet(datapoint2,ack);
   while ((ack!=channel)&&(i<20))
     {
     delay(1,0);
     i=i+1;
     dpGet(datapoint2,ack);
     }
   i=0;
   //ramp down HV's
   if( ack==channel) OK=1;
   channel = 193-64 | (( iState & 0x00ff )<<8);
     dpSetWait(datapoint,channel);
   dpGet(datapoint2,ack);
   while ((ack!=channel)&&(i<20))
     {
     delay(1,0);
     i=i+1;
     dpGet(datapoint2,ack);
     }
   i=0;
   if( ack==channel&&OK==1) OK=2;
   // send back confirmation to DAQ if both LV and HV have been ramped to STB1
   if(OK==2) dpSetWait("changeState.response:_original.._value",0);
   }


 }
 else if(channel<48){
 ChannelNo = channel;
 // Ramp up one channel, i.e LV and HV
 if(iState==1)
   {
   OK=0;
   channel = channel | (( iState & 0x00ff )<<8);
   dpSetWait(datapoint,channel);
   dpGet(datapoint2,ack);
   while ((ack!=channel)&&(i<10))
     {
     delay(1,0);
     i=i+1;
     dpGet(datapoint2,ack);
     }
   i=0;
   if( ack==channel) OK=1; 
   DebugN("ack0",ack,OK,channel);
   dpSetWait(datapoint,channel+64);   
   // check that Ewa has done the transition
   dpGet(datapoint2,ack);
   while ((ack!=channel+64)&&(i<10))
     {
     delay(1,0);
     i=i+1;
     dpGet(datapoint2,ack);
     }
   i=0;
   if( ack==channel+64&&OK==1) OK=2; 
   // send back confirmation to DAQ
   DebugN("ack1",ack,OK,channel+64);
   if(OK==2){
   	 dpSetWait("changeState.response:_original.._value",0);
   	 sprintf(datapoint5,"Crate%02d.Channel%02d.State:_original.._value",crate, ChannelNo);
   	 dpSetWait(datapoint5,1);
   	 return 1;
   }
   }


if(iState==2)
   {
   OK=0;
   // ramp to LV STB1
   ichan=channel;
   DebugN(channel,iState);
   channel = channel | (( iState & 0x00ff )<<8); 
   DebugN(channel);
   dpSetWait(datapoint,channel); 
   dpGet(datapoint2,ack);
   while ((ack!=channel)&&(i<10))
     {
     delay(1,0);
     i=i+1;
     dpGet(datapoint2,ack);
     }
   i=0;
   if( ack==channel) OK=1;	
   //ramp HV to SBT1  
   dpSetWait(datapoint,channel+64);
   // check that Ewa has done the transition
   dpGet(datapoint2,ack);

   while ((ack!=channel+64)&&(i<10))
     {
     delay(1,0);
     i=i+1;
     dpGet(datapoint2,ack);
     }
   i=0;
   if(ack==channel+64&&OK==1) OK=2;
   DebugN("ackhv",ack,OK,channel+64);
   // send back confirmation to DAQ
   if(OK==2)
   dpSetWait("changeState.response:_original.._value",0);
   }

   if(iState==0)
   {
   channel = channel | (( iState & 0x00ff )<<8);
   dpSetWait(datapoint,channel);
   dpGet(datapoint2,ack);
   while ((ack!=channel)&&(i<10))
     {
     delay(1,0);
     i=i+1;
     dpGet(datapoint2,ack);
     DebugN("ack",ack);
     } 
   i=0;
   DebugN("acklv",ack,OK,channel);
   if( ack==channel) OK=1; 
   dpSetWait(datapoint,channel+64);   
   // check that Ewa has done the transition
   dpGet(datapoint2,ack);
   while ((ack!=channel+64)&&(i<10))
     {
     delay(1,0);
     i=i+1;
     dpGet(datapoint2,ack);
     } 
   i=0;
   if( ack==channel+64&&OK==1) OK=2; 
   // send back confirmation to DAQ
   DebugN("ackhv",ack,OK,channel+64);
   if(OK==2) {
   		dpSetWait("changeState.response:_original.._value",0);
   		sprintf(datapoint5,"Crate%02d.Channel%02d.State:_original.._value",crate, ChannelNo);
   		DebugN(crate,channel);
   	 	dpSetWait(datapoint5,0);
   	 	return 1;
   }
   }

if(iState==4)
   {
   OK=0;  
   // ramp the LV's from STB to ON leave HV to STB
   channel = channel | (( 1 & 0x00ff )<<8);
   dpSetWait(datapoint,channel);
   // check that Ewa has done the transition
     dpGet(datapoint2,ack);
   while ((ack!=channel)&&(i<20))
     {
     delay(1,0);
     i=i+1;
     dpGet(datapoint2,ack);
     DebugN("LV2",ack);
     }
   if(ack==channel) OK=1;
   i=0;  
   if(OK==1)
   dpSetWait("changeState.response:_original.._value",0);
  } 
 if(iState==5)
   {
     // ramp dwon the LV's from ON to STB and HV to STB
   iState=2;
   OK=0;
   // ramp down LV's
   channel = channel| (( iState & 0x00ff )<<8);
   dpSetWait(datapoint,channel);
   dpGet(datapoint2,ack);
   while ((ack!=channel)&&(i<20))
     {
     delay(1,0);
     i=i+1;
     dpGet(datapoint2,ack);
     }
   i=0;
   //ramp down HV's
   if( ack==channel) OK=1;
   channel = channel +64 | (( iState & 0x00ff )<<8);
     dpSetWait(datapoint,channel);
   dpGet(datapoint2,ack);
   while ((ack!=channel)&&(i<20))
     {
     delay(1,0);
     i=i+1;
     dpGet(datapoint2,ack);
     }
   i=0;
   if( ack==channel&&OK==1) OK=2;
   // send back confirmation to DAQ if both LV and HV have been ramped to STB1
   if(OK==2) dpSetWait("changeState.response:_original.._value",0);
   }
  }
  return 0;
}

Read() 
{
int i,icard, channel, statusLV, statusHV,statusLVCard;
string datapoint, datapoint2,datapoint3;
for (i=0; i<=47; i++){
dpSetWait("Crate00.Controller.CCchRead.Send:_original.._value",i);
channel=i+64;
delay(0,10);
dpSetWait("Crate00.Controller.CCchRead.Send:_original.._value", channel);
delay(0,10);
  }
}
