// 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:  17.11.2003 - first version - H. Sandaker
//                   27.11.2003 - modify it according to changes in runstate 
//					    DDC commands P.Ferrari
//                   07.01.2004 - Adapt to change of DDC command
//                   08.01.2004 - Added loading of Cnf database HS & PM
//                   28.01.2004 - Both loading of Cnf databas and hardcoded values
//                                for on/off/stb/fatals - HS
//                   
//===================================-======================================*/

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


void loadConfiguration(string Text, bool Flag) 
{
int iRST,skip,timeout;
int crate,channel;
string allChannels;
string sParameter;
dyn_string para_split;


//Get Values from DAQ
  dpGet("loadConfiguration.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|State|timeout
  sscanf(para_split[1],"%d", crate);
  sscanf(para_split[2],"%d", iRST);
  sscanf(para_split[3],"%d", timeout);
  DebugN("NEW",crate,iRST);

// Load OFF parameters OFF=> iRST=0, ON=> iRST=1
if (Flag==1)
   {
   dpSet("Info.Name:_original.._value", "CS: Loading new configuration to CC");
   DebugN("CS: Loading new configuration to CC");
   LoadConfig(iRST, crate); // Load configuration into ELMB
   
     if (iRST==255) {
        iRST=0;
        LoadConfig(iRST, crate);
        DebugN("state 0");
        dpSet("Info.Name:_original.._value", "CS: Loading state OFF to CC");
        iRST=1;
        LoadConfig(iRST, crate);
        DebugN("state 1");
        dpSet("Info.Name:_original.._value", "CS: Loading state ON to CC");
        iRST=2;
        LoadConfig(iRST, crate);
        DebugN("state 2");
        dpSet("Info.Name:_original.._value", "CS: Loading state STB to CC");
        iRST=128;
        LoadConfig(iRST, crate);
        DebugN("state 128");
        dpSet("Info.Name:_original.._value", "CS: Loading fatal alarms OFF to CC");
        iRST=129;
        LoadConfig(iRST, crate);
        DebugN("state 129");
        dpSet("Info.Name:_original.._value", "CS: Loading fatal alarms ON to CC");
        iRST=130;
        LoadConfig(iRST, crate);
        DebugN("state 130");
        dpSet("Info.Name:_original.._value", "CS: Loading fatal alarms STB to CC");
        }
     else {
        LoadConfig(iRST, crate);;
        DebugN("state", iRST);
        }
        // change the values in the PVSS datapoints to be sure that we are reading back the 
        // configuration in the ELMB
   // change(iRST);       
   // TestConfig(iRST); // Test configuration in ELMB
   dpSet("loadConfiguration.trigger:_original.._value",0);
   DebugN("trigger");
   dpSetWait("loadConfiguration.response:_original.._value",0);
   }
}


LoadConfig(int iRST, int crate)
{
dyn_errClass err;
int  k, iDBtype;
int iStoreEnd;
string addressCC, addressCC2;


//Tell crate controller what datapoints to store 0 = off:
  sprintf(addressCC, "Crate%02d.Controller.CCcf_RST.Send:_original.._value", crate); 
  dpSetWait(addressCC, iRST);
//Info:
//  dpSet("Info.Name:_original.._value", "CS: Setting CC in ", iRST, "mode");
  dpSet("Info.Name:_original.._value", "CS: Setting CC...");
  DebugN("CS: Setting CC in", iRST," mode");

//Trigger loading of OFF parameters (0) from file to PVSS 
// SDO's are sendt. Choose between hardcoded values and database values for loading:
  dpGet("ChoiceDB.Data:_online.._value", iDBtype);
  
     if (iDBtype==1){ 
        Test(iRST);
        }
     else if (iDBtype==0){ 
        LoadCNDB(iRST);
        //DebugN("DBtype", iDBtype);
        }
     
     //When finished tell crate controller to save these values: 
     dpSetWait("Crate00.Controller.CCcf_Set.Send:_original.._value", 1702257011);
    //Info:
     dpSet("Info.Name:_original.._value", "CS: Saving parameters to CC memory");
     DebugN("CS: Saving parameters to CC memory");
       
   // Read the save-acknowledgement to check if storing values has finished
   delay(120,0);
   sprintf(addressCC2, "Crate%02d.Controller.CCcf_RST.Recv:_original.._value", crate); 
   dpGet(addressCC2, iStoreEnd); 
   DebugN("RST",iStoreEnd);
   if (iStoreEnd == 255){
       dpSet("Info.Name:_original.._value", "CS: Finished saving parameters to CC memory");
       DebugN("CS: Finished saving parameters to CC memory");   
       }
   else {
       dpSet("Info.Name:_original.._value", "CS: Stopped - Timeout");
       //DebugN("RST",iStoreEnd);     
       }
      
}


//------------------------------------------------------------------
//
//    LOADING VALUES FROM CONFIGURATION DATABASE - .TXT FILE
//
//------------------------------------------------------------------

LoadCNDB(int iRST) {

// Load database into Send values

int i, j, valuemax, tell;
file paraDB;
int id, channelNB;
string address, addressF;
// Parameters for all values in one line of the file opened:
string s02w, s03w,  s04w, s05w, s06w, s07w, s08w, s09w,
       s10w, s11w, s12w, s13w, s14w, s15w, s16w, s17w, s18w, s19w, s20w, s21w;
string fstr, name;
dyn_float sendTest, sendTestF;
float errorOpen;
// Values relevant for the changing of states
float offFatalL, offWarningL, offValue, offWarningH, offFatalH,
      stbFatalL, stbWarningL, stbValue, stbWarningH, stbFatalH, 
      onFatalL, onWarningL, onValue, onWarningH, onFatalH;
// Names of the corresponding parameters to be used in addressing
string LVch_Vcc, LVch_Vdd, LVchVCSV, LVchPINV,LVchDTrp, LVchCTrp, LVchTLim, LVchTTrp, 
       LVchCLKS, LVchCLKR, LVchVOut, HVchVolt, HVchITrp, HVchRamp; 

// Open Database
paraDB = fopen("Cnf_Para.txt","r");   

//DebugN("iRST", iRST);
DebugN("Start Config");

// Check for errors
errorOpen = ferror(paraDB);

if (errorOpen!=0) {
   DebugN("File Cnf_Para.txt did not open / correctly");
   }

else {

     // Loop all parameters on one channel
//     valuemax=1296;
     valuemax=60;
     for (i=0; i<=valuemax; i++) {

         // GET VALUES:
         //fscanf (f,"%f",value[i]); // read as float again  
         //DebugN(value[i]); // output for checking
  
         fgets(fstr, 300, paraDB);        

         //Take away "'s!
         strreplace(fstr, "\"", "");
         //DebugN(fstr);


         //DebugN ("i", i);
         sscanf (fstr,"%d%d%s%s%s%f%f%f%f%f%s%f%f%f%f%f%s%f%f%f%f%f", 
                id, channelNB, name, s03w, offFatalL, offWarningL, offValue, offWarningH, offFatalH, 
                s10w, stbFatalL, stbWarningL, stbValue, stbWarningH, stbFatalH, 
                s16w, onFatalL, onWarningL, onValue, onWarningH, onFatalH);
         //DebugN ("Reading Channel NB: ", i);

         // Correction for error in conf_para file:channel nb starts with 1 not 0 
         channelNB = channelNB -1;      

         
         // Load datapoint ON STATE, for send values lines 2,6,10,12,16,17,18,19,20,21,22,24,26,27
         // the array sendTest starts with line nb 1 in cnf_para, for list of values - names see bottom of script
         sendTest = makeDynFloat(0,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,1,1,1,1,1,1,1,0,1,0,1,1);
         sendTestF = makeDynFloat(0,0,0,0,0,0,0,0,0,0,0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 1, 0);
                                //0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27 

         j= i+1 - 27*channelNB; 
         DebugN("channelNB", channelNB, "i", i, "j", j);
                  
         if (channelNB>=0){
            
            if (sendTest[j]==1) {
               // Check if send value according to array;
               sprintf(address, "Crate00.Channel%02d.%s.Send:_original.._value", channelNB, name );   
               //choise of RST parameters:
               if (iRST == 0) { 
                  dpSet(address, offValue);
                  DebugN("off", offValue);
                  }
               if (iRST == 1) { 
                  dpSet(address, onValue);
                  DebugN("on", onValue);
                  }
               if (iRST == 2) { 
                  dpSet(address, stbValue);
                  DebugN("stb", stbValue);
                  } 
               }
               
            if (sendTestF[j]==1) {
               // Check if send value according to array;
               sprintf(addressF, "Crate00.Channel%02d.%s.Send:_original.._value", channelNB, name );  
               //choise of RST parameters: 
               if (iRST == 128) { 
                  dpSet(addressF, offFatalH);
                  DebugN("offFatal", offFatalH);
                  }
               if (iRST == 129) { 
                  dpSet(addressF, onFatalH);
                  DebugN("onFatal", onFatalH);
                  }
               if (iRST == 130) { 
                  dpSet(addressF, stbFatalH);
                  DebugN("stbFatal", stbFatalH);
                  }         
               }
          }
         // Missing set upper alarms!!  
     } 
}

//dpSetWait(datapoint1, initValue[j]);
//rewind(ParaDB);
fclose(paraDB);              
//fclose(Cnf_ParaM.txt);  
}
                 
//------------------------------------------------------------------
//
//    ROUTINE USED FOR DB TESTING - HARDCODED VALUES
//
//------------------------------------------------------------------

Test(int iRST) {

// Function to simulate the Loading of values from file to PVSS

int icard, channel, statusLV, statusHV,statusLVCard;
string datapoint1, datapoint2,datapoint3; 
dyn_errClass err;
int i, j, l;
dyn_string valsetLV, valsetHV, valsetLVfatal, valsetHVfatal; 
dyn_float initValueLV, initValueHV, initValueLVfatal, initValueHVfatal;

DebugN("Start Hardcoded");

if (iRST == 0) { 
   initValueLV = makeDynFloat(46.5,15,0,0,0,0,50,50,50,60,0,0,0);
   initValueHV = makeDynFloat(0,1100000,3);
   }
if (iRST == 1) { 
   initValueLV = makeDynFloat(46.5,15,3.7,4,4,6,50,50,50,60,0,0,1);
   initValueHV = makeDynFloat(150,1100000,3);
   }
if (iRST == 2) { 
   initValueLV = makeDynFloat(46.5,15,2.5,4,4,6,50,50,50,60,0,0,1);
   initValueHV = makeDynFloat(20,1100000,3);
   }   
if (iRST == 128) { 
   initValueLVfatal = makeDynFloat(15,15,1);
   initValueHVfatal = makeDynFloat(10,600000); //units 10 nA!!
   }
if (iRST == 129) { 
   initValueLVfatal = makeDynFloat(26,26,1);
   initValueHVfatal = makeDynFloat(10,600000); // units 10 nA!!
   }
if (iRST == 130) { 
   initValueLVfatal = makeDynFloat(22,22,1);
   initValueHVfatal = makeDynFloat(10,600000); // units 10 nA!!   
}      

valsetLV = makeDynString("LVcaTrip","LVcaMask","LVch_Vcc","LVch_Vdd",
                         "LVchVCSV","LVchPINV","LVchDTrp","LVchCTrp",
                         "LVchTTrp","LVchTLim","LVchCLKS","LVchCLKR",
                         "LVchVOut");
valsetHV = makeDynString("HVchVolt","HVchITrp","HVchRamp");

valsetLVfatal = makeDynString("LVchTTrp","LVchTLim", "LVchVOut");
                             //fatalTemp1, fatalTemp2,fatalVout                          
                        
valsetHVfatal = makeDynString("HVchVolt","HVchITrp");
                            // FatalVolt , FatalCurrent 

//Loading of fatals:
if (iRST==128 || iRST==129 || iRST ==130){
     for (l=0; l<=47; l++){
         for (i=1; i<=2; i++) {
             sprintf(datapoint1, "Crate00.Channel%02d.%s.Send:_original.._value",l,valsetHVfatal[i] );
             dpSetWait(datapoint1, initValueHVfatal[i]);     
             //DebugN(" HV channel", l, valsetHVfatal[i], " = ",initValueHVfatal[i]);
             }         
         for (j=1;j<=2;j++){
             sprintf(datapoint1, "Crate00.Channel%02d.%s.Send:_original.._value",l,valsetLVfatal[j] );
             dpSetWait(datapoint1, initValueLVfatal[j]);
             //DebugN(" LV channel", l, valsetLV[j], " = ",initValueLV[j]);
             }

        }
    }

else if (iRST==0 || iRST==1 || iRST==2) {
// Loading off values for the parameters: 
     for (l=0; l<=47; l++){
         for (i=1; i<=3; i++) {
             sprintf(datapoint1, "Crate00.Channel%02d.%s.Send:_original.._value",l,valsetHV[i] );
             dpSetWait(datapoint1, initValueHV[i]);     
             //DebugN(" HV channel", l, valsetHV[i], " = ",initValueHV[i]);
             }
         
         for (j=3;j<=13;j++){
             sprintf(datapoint1, "Crate00.Channel%02d.%s.Send:_original.._value",l,valsetLV[j] );
             dpSetWait(datapoint1, initValueLV[j]);
             //DebugN(" LV channel", l, valsetLV[j], " = ",initValueLV[j]);
             }

        }
     }
  err = getLastError();
  if (dynlen(err) > 0)
    errorDialog(err);       
 
}



change(int iRST) {

// Function to change the values in PVSS datapoints to make sure we are reloading
//  the values from ELMB

int icard, channel, statusLV, statusHV,statusLVCard;
string datapoint1, datapoint2,datapoint3; 
dyn_errClass err;
int i, j, l;
dyn_string valsetLV, valsetHV; 
dyn_float initValueLV, initValueHV;

if (iRST == 0) { 
   initValueLV = makeDynFloat(0,0,0,0,0,0,0,0,0,0,0,0,0);
   initValueHV = makeDynFloat(0,0,0);
   }
if (iRST == 1) { 
   initValueLV = makeDynFloat(0,0,0,0,0,0,0,0,0,0,0,0,0);
   initValueHV = makeDynFloat(0,0,0);
   }
if (iRST == 2) { 
   initValueLV = makeDynFloat(0,0,0,0,0,0,0,0,0,0,0,0,0);
   initValueHV = makeDynFloat(0,0,0);
   }

valsetLV = makeDynString("LVcaTrip","LVcaMask","LVch_Vcc","LVch_Vdd",
                         "LVchVCSV","LVchPINV","LVchDTrp","LVchCTrp",
                         "LVchTTrp","LVchTLim","LVchCLKS","LVchCLKR",
                         "LVchVOut");
valsetHV = makeDynString("HVchVolt","HVchITrp","HVchRamp");


// Loading off values for the parameters: 
 for (l=0; l<=47; l++){
DebugN("Changing PVSS datapoints values for cross check");
     for (i=1; i<=3; i++) {
         sprintf(datapoint1, "Crate00.Channel%02d.%s.Send:_original.._value",l,valsetHV[i] );
         dpSetWait(datapoint1, initValueHV[i]);     
         }
         
     for (j=3;j<=13;j++){
         sprintf(datapoint1, "Crate00.Channel%02d.%s.Send:_original.._value",l,valsetLV[j] );
         dpSetWait(datapoint1, initValueLV[j]);
         }

     }
 
  err = getLastError();
  if (dynlen(err) > 0)
    errorDialog(err);       
 
}


TestConfig(int iRST) {

dyn_errClass err;
int  k;
int iStoreEnd;

//Tell crate controller what datapoints to read 0 = off:

dpSetWait("Crate00.Controller.CCcf_RST.Send:_original.._value", iRST);
   dpSet("Info.Name:_original.._value", "CS: chosing to read parameters from CC");
   DebugN("CS: chosing to read parameters from CC");

//Tell crate controller to send off parameters back to PVSS:
  
dpSetWait("Crate00.Controller.CCcf_Set.Send:_original.._value", 1684107116);
   dpSet("Info.Name:_original.._value", "CS: Reading parameters from CC memory...");
   DebugN("CS: Reading parameters from CC memory...");  

delay(10);
//Trigger reading of OFF parameters (0) from file to PVSS 
// SDO's are sendt

Read();
   dpSet("Info.Name:_original.._value", "CS: Reading parameters from CC memory");
   DebugN("CS: Reading parameters from CC memory");  
   
// check if readed values has finished
delay(10,0);

     dpGet("Crate00.Controller.CCcf_RST.Recv:_original.._value", iStoreEnd); 
     if (iStoreEnd = 255){
        dpSet("Info.Name:_original.._value", "CS: Finished reading parameters to CC memory");
        DebugN("CS: Finished reading parameters to CC memory");   
        }
     else {
        dpSet("Info.Name:_original.._value", "CS: Stopped - Timeout");
        DebugN("CS: Stopped - Timeout");     
     } 
// check if values are ok:
   Check(iRST);

}

Read() {

int i,icard, channel;
delay(0,10);

DebugN("CS: Reading Values"); 
dpSet("Info.Name:_original.._value", "CS: Reading values...");
 
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);
    }
}


Check (int iRST) {
string datapoint1; 
dyn_errClass err;
int i, j, l;
float abs,x;
dyn_string valsetLV, valsetHV; 
dyn_float initValueLV, initValueHV, readValueLV, readValueHV;
int HV, LV;

valsetLV = makeDynString("LVcaTrip","LVcaMask","LVch_Vcc","LVch_Vdd",
                         "LVchVCSV","LVchPINV","LVchDTrp","LVchCTrp",
                         "LVchTTrp","LVchTLim","LVchCLKS","LVchCLKR",
                         "LVchVOut");
valsetHV = makeDynString("HVchVolt","HVchITrp","HVchRamp");

     if (iRST == 0) { 
        initValueLV = makeDynFloat(46,15,0,0,0,0,50,50,50,60,0,0,0);
        initValueHV = makeDynFloat(0,1100,3);
        }
     if (iRST == 1) { 
        initValueLV = makeDynFloat(46.5,15,3.5,4,4,6,50,50,50,60,0,0,1);
        initValueHV = makeDynFloat(300,1100,3);
        }
     if (iRST == 2) { 
        initValueLV = makeDynFloat(46.5,15,2.0,4,4,6,50,50,50,60,0,0,1);
        initValueHV = makeDynFloat(20,1100,3);
        }


// Reading values for the parameters: 
 for (l=0; l<=47; l++){
     HV=0;
     LV=0;
     for (i=1; i<=3; i++) {
         sprintf(datapoint1, "Crate00.Channel%02d.%s.Send:_original.._value",l,valsetHV[i] );
         dpGet(datapoint1, readValueHV[i]);
         DebugN(" read value Hv channel= ",l," is ",readValueHV[i], "set value is =", initValueHV[i]);
         x=readValueHV[i] - initValueHV[i];
	   abs=(x<0) ? -x : x; // abs= abs(x)
	   //DebugN( "absolute value", abs);
         if (abs <0.01) {
            HV = HV +1; 
            }     
         }        
     for (j=3;j<=13;j++){
         sprintf(datapoint1, "Crate00.Channel%02d.%s.Send:_original.._value",l,valsetLV[j] );
         dpGet(datapoint1, readValueLV[j]);
         DebugN(" read value LV channel= ",l," is ",readValueLV[j], "set value is =", initValueLV[j]);
         x=readValueLV[j] - initValueLV[j];
	   abs=(x<0) ? -x : x; // abs= abs(x)
         if (abs <0.01) {
            LV = LV +1; 
            } 
         }
     if (HV == 3 && LV == 11) {     
        DebugN("channel ok:", l);
        }
     else {
        DebugN("channel bad:", l);
        }
     }
        
}
// 1	1	"LVchStat"	
// 2	1	"LVch_Vcc"	
// 3	1	"LVps_Vcc"	
// 4	1	"LVretVcc"	
// 5	1	"LVch_Icc"	
// 6	1	"LVch_Vdd"	
// 7	1	"LVps_Vdd"	
// 8	1	"LVretVdd"	
// 9	1	"LVch_Idd"	
// 10	1	"LVchVCSV"	
// 11	1	"LVchVCSI"	
// 12	1	"LVchPINV"	
// 13	1	"LVchPINI"	
// 14	1	"MOch_Tm0"	
// 15	1	"MOch_Tm1"	
// 16	1	"LVchDTrp"	
// 17	1	"LVchCTrp"	
// 18	1	"LVchTLim"		
// 19	1	"LVchTTrp"	
// 20	1	"LVchCLKS"	
// 21	1	"LVchCLKR"	
// 22	1	"LVchVOut"	
// 23	1	"HVchStat"	
// 24	1	"HVchVolt"	
// 25	1	"HVchCurr"	
// 26	1	"HVchITrp"	
// 27	1	"HVchRamp"

// Configuration DB


