**********
* EXAMLE *
**********

State1 // RT application state name
==========
1. // Numbered GAMs in order of execution
if (signal_A == 1) // Execution function of the GAM
{
    set signal_B = 3
    change state to State2
}
----------



*****************
* RT APP STATES *
*****************

WaitStandby
==========
1. // DONE
if (EC-GN-P01-GAF:PLC4110-CON-OPGY1 == 0) //If a Gyrotron is not selected by PLC.
{
    change state to Disabled
}
----------
2. // DONE
if (EC-GN-P01-GPF:PLC4110-YTS-ST1R == 1) //If STANDBY signal come from PLC, start Coil&Fil PSs.
{
    // TODO should these signals be set only once every time this state is entered?
    set signal EC-GN-P01-GAF-MCPS:PSU2120-ACT-SP = 1
    set signal EC-GN-P01-GAF-GCPS:PSU2130-ACT-SP = 1
    set signal EC-GN-P01-GAF-FHPS:PSU2610-AUTO-START = 1
}
----------
3. // DONE
if (EC-GN-P01-GAF-MCPS:PSU2120-ACT-RB == 1
    AND
    EC-GN-P01-GAF-MCPS:PSU2120-CURR-MON > 0
    AND
    EC-GN-P01-GAF-FHPS:PSU2610-OUTON-RB == 1
    AND
    EC-GN-P01-GAF-FHPS:PSU2610-CURR-RB > 0)
{
    change state to Offline
}
----------



Disabled
==========
1. // DONE
if (EC-GN-P01-GAF:PLC4110-CON-OPGY1 == 1)
{
    change state to WaitStandby
}
----------



Offline
==========
1. // DONE
if (EC-GN-P01-GAF:PLC4110-CON-OPGY1 == 0) //If Gyrotron selection is turned off.
{
    change state to Disabled
}
----------
2. // DONE
// If READY signal come from PLC is equal 1, app starts CCPS.
if (EC-GN-P01-GPF:PLC4110-YTS-ST2R == 1
    AND
    EC-GN-P01-GAF-CCPS:PLC4110-YON-CCPS1 == 1)
{
    // TODO should this signal be set only once every time this state is entered?
    set signal EC-GN-P01-GAF-CCPS:PSU2320-OUTON-SP = 1
}
----------
3. // DONE (with a temporary signal that needs to be changed when the record is added)
// TODO: Do we also have to check, that GAM 2. executed? So do we also have to check that EC-GN-P01-GPF:PLC4110-YTS-ST2R == 1?
if (EC-GN-P01-GAF-CCPS:PSU2320-STAT == 1) // TODO: there is no signal named EC-GN-P01-GAF-CCPS:PSU2320-STAT
                                          // MEMO: I need add this record to check whether CCPS in running or stop.
{
    change state to WaitPermit
}
----------
4. // DONE
// Wait CSV-LOAD trigger. When the app detect it, save data into the app.
if (EC-GN-P01-GAF:STAT-CSV-LOAD == 1)
{
    open csv file (file name: EC-GN-P01-GAF:STAT-CSV-NAME)
    load time series data into memory
    write data into EPICS waveform PSs.(EC-GN-P01-???:STAT-PREP-WF) // TODO do we realy write first data here or do we wait for PreHeating?
    set signal EC-GN-P01-GAF:STAT-CSV-LOADED = 1 // TODO do we write 1 here?
    If there is error, write EC-GN-P01-GAF:STAT-CSV-ERROR. // TODO there is no signal named EC-GN-P01-GAF:STAT-CSV-ERROR
}


WaitPermit
==========
1. // DONE
if (EC-GN-P01-GAF:PLC4110-CON-OPGY1 == 0) //If Gyrotron is un-selected.
{
    change state to Disabled
}
----------
2. // DONE
if (EC-GN-P01-GAF:STAT-PREP-MODE == 1
    AND
    EC-GN-P01-GAF:PLC4110-CON-GY1PRM == 1)
{
    change state to PreHeating
}
----------
3. // DONE
if (EC-GN-P01-GAF:STAT-PREP-MODE == 0
    AND
    EC-GN-P01-GAF:PLC4110-CON-GY1PRM == 1)
{
    change state to WaitReady
}
----------
4. // DONE
if (EC-GN-P01-GAF:STAT-CSV-LOAD == 1)
{
    open csv file (file name: EC-GN-P01-GAF:STAT-CSV-NAME)
    load time series data into memory
    write data into EPICS waveform PSs.(EC-GN-P01-???:STAT-PREP-WF)
    set signal EC-GN-P01-GAF:STAT-CSV-LOADED = 1
    If there is error, write EC-GN-P01-GAF:STAT-CSV-ERROR.
}

PreHeating
==========
1. // DONE
every 10 ms do
{
    else
    {
        // TODO do we use float32 for the type of waveform signals?
        // TODO is this the right order of columns? Time point is in column 1.
        // TODO on what signal do we write time?
        set signal EC-GN-P01-PB1F:PSU1000-EREF = setpoint column 2 
        set signal EC-GN-P01-PA1F:PSU3000-EREF  = setpoint column 3 // TODO there are two EC-GN-P01-PA1F:PSU3000-EREF signals. One ending with -P and one with -N.
        set signal EC-GN-P01-GAF-MCPS:PSU2120-TRG-CURR-SET  = setpoint column 4
        set signal EC-GN-P01-GAF-GCPS:PSU2130-TRG-CURR-SET = setpoint column 5
        set signal EC-GN-P01-GAF-FHPS:PSU2320-EREF  = setpoint column 6
    }
}
----------
2. // DONE
if (time == 0)
{
    change state to WaitReady
}
----------


WaitReady
==========
1. // DONE
if (EC-GN-P01-PB1F:PSU1000-YSTA == 1
    AND
    EC-GN-P01-PA1F:PSU3000-YSTA == 1)
{
    change state to WaitHVON
}
----------


WaitHVON
==========
1. // DONE
if (EC-GN-P01-GPF:PLC4110-YTS-ST3R == 1)// Check ON signal from PLC. This signal come when PLC check the operation operation possible conditions.
{
    change state to HVArming
}
----------
2. // DONE
if (EC-GN-P01-GPF:PLC4110-YTS-ST3R == 1)
{
    start HVON timer
}
----------



HVArming //HVArming is a state to startup HV generation in APS and BPS.
==========
1.
at specified time // TODO: Where do I get this specified time? And is it a countdown time or what?
                  // MEMO: Time is specified by PVs (EC-GN-P01-PB1F:STAT-DT-HVON). When app detect HVON from PLC, it is t=0.
{
    set signal EC-GN-P01-PB1F:PSU1000-CON-HV = 1
}
----------
2.
at specified time // TODO: Where do I get this specified time? And is it a countdown time or what?
                  // MEMO: Time is specified by PVs (EC-GN-P01-PA1F:STAT-DT-HVON)
{
    set signal EC-GN-P01-PA1F:PSU3000-CON-HV = 1
}
----------
3.
if (EC-GN-P01-PB1F:PSU1000-CON-HV == 1
    AND
    EC-GN-P01-PA1F:PSU3000-CON-HV == 1
    AND
    EC-GN-P01-GPF::PLC4110-YSTA-MPSS == 0) // MEMO: Both HV PVs are 1. i.e.Both PSs are charged HV. and is in async mode.
{
    change state to HVArmed
}
----------
4.
if (EC-GN-P01-PB1F:PSU1000-CON-HV == 1
    AND
    EC-GN-P01-PA1F:PSU3000-CON-HV == 1
    AND
    EC-GN-P01-GPF::PLC4110-YSTA-MPSS == 1) // MEMO: HVPS HVs are ON and is in SYNC mode.
{
  Change state to HVArmedESDN
}
----------
5.
  count up elapsed time (time from HVON detection)
  Write time to EC-GN-P01-GAF:STAT-ELAPSED


HVArmed
==========
1.
if (EC-GN-P01-GPF:PLC4110-YTS-ST3R == 0) // TODO: when do we go from HVArmed to Offline?
                                         // MEMO: move to Offline when ON signal from PLC is turned off.
{
    change state to Offline
}
----------
2.
// TODO: "(Entry) Write EC-GN-P01-GAF:PCF4210-YTS-GA1" What does Entry mean? Does it mean to do something
// only on the first cycle when we enter this state? What do I write to signal EC-GN-P01-GAF:PCF4210-YTS-GA1?
// MEMO: EC-GN-P01-GAF:PCF4210-YTS-GA1 is a PV that fast controller notifies Gyrotron operation state to PLC.
// When enter the HVArmed state, App writes 1 to this EPICS PV.
----------
3.
if (EC-GN-P01-PB1F:PSU1000-CON-SW == 1) // TODO: when do we go from HVArmed to HVInjectionBPS?
      // MEMO: If MHVPS HV is turned ON first, goto this state.
{
    change state to HVInjectionBPS
}
----------
4.
if (EC-GN-P01-PMF:PSU0000-CON-SW == 1) // TODO: when do we go from HVArmed to HVInjectionMHVPS?
      // MEMO: If BPS HV is turned ON first, goto this state.
{
    change state to HVInjectionMHVPS
}
----------
5.
  count up elapsed time (time from HVON detection)
  Write time to EC-GN-P01-GAF:STAT-ELAPSED
----------
6.
if (EC-GN-P01-GPF::PLC4110-YSTA-MPSS == 1) //When SYNC mode turned ON.
{
    change state to HVArmedESDN
}
----------

HVArmedESDN // Start ESDN command, waveform subscription.
==========
1.
if (EC-GN-P01-GPF:PLC4110-YTS-ST3R == 0)
{
    change state to Offline
}
----------
2.
if (EC-GN-P01-PB1F:PSU1000-CON-SW == 1)
{
    change state to HVInjectionBPSESDN
}
----------
3.
if (EC-GN-P01-PMF:PSU0000-CON-SW == 1)
{
    change state to HVInjectionMHVPSESDN
}
----------
4.
  count up elapsed time (time from HVON detection)
  Write time to EC-GN-P01-GAF:STAT-ELAPSED
----------
6.
if (EC-GN-P01-GPF::PLC4110-YSTA-MPSS == 0) //When SYNC mode turned ON.
{
    change state to HVArmed
}
----------

HVInjectionBPS
==========
HVInjectionMHVPS
==========
1.
// MEMO: Write Gyrotron state PV (HVInjection) to notify PLC.
Write 1 to EC-GN-P01-GAF:PCF4210-YTS-GA2.
----------
// TODO: Following questions/states are for ALL of the above states
2. (Exist in HVInjection BPS)
set signal EC-GN-P01-PA1F:PSU3000-CON-SW = 1 // TODO when do we set this signal
// MEMO: Countdown time for EC-GN-P01-PA1F:STAT-DT-SWON
----------
2. (Exist in HVInjection MHVPS)
set signal EC-GN-P01-PB1F:PSU1000-CON-SW = 1 // TODO when do we set this signal
// MEMO: Countdown time for EC-GN-P01-PB1F:STAT-DT-SWON
----------
3.
set signal EC-GN-P01-PMF:PSU0000-CON-SW = 1 // TODO when do we set this signal
// MEMO: Countdown time for EC-GN-P01-PMF:STAT-DT-SWON
----------
4.
// TODO when to switch to RFON?
// MEMO: Go to RFON state when All switch PVs are 1. and the mode is async.
if (EC-GN-P01-PA1F:PSU3000-CON-SW == 1 AND
    EC-GN-P01-PB1F:PSU1000-CON-SW == 1 AND
    EC-GN-P01-PMF:PSU0000-CON-SW == 1)
{
    change state to RFON
}
----------
5.
  count up elapsed time (time from HVON detection)
  Write time to EC-GN-P01-GAF:STAT-ELAPSED
----------

HVInjectionESDN
==========
1.
// MEMO: Write Gyrotron state PV (HVInjection) to notify PLC.
Write 1 to EC-GN-P01-GAF:PCF4210-YTS-GA2.
----------
2.
set signal EC-GN-P01-PA1F:PSU3000-CON-SW = 1
//      Write 1 when ESDN command give a command.
----------
3.
set signal EC-GN-P01-PB1F:PSU1000-CON-SW = 1
//      Write 1 when ESDN command give a command.
----------
4.
set signal EC-GN-P01-PMF:PSU0000-CON-SW = 1
//      Write 1 when ESDN command give a command.
----------
5.
// TODO when to switch to RFONESDN?
// MEMO: Go to RFON state when All switch PVs are 1. and the mode is sync.i,e. change from HVInjectionxxxESDN
if (EC-GN-P01-PA1F:PSU3000-CON-SW == 1 AND
    EC-GN-P01-PB1F:PSU1000-CON-SW == 1 AND
    EC-GN-P01-PMF:PSU0000-CON-SW == 1)
{
    change state to RFONESDN
}
----------

RFON
==========
// TODO is this correct?
1.
// This only executes on the last cycle before we move to HVArmed
if (EC-GN-P01-GAF:STAT-BEAMON-TIME >= EC-GN-P01-GAF:STAT-DT-SHOTLEN)
{
    set signal EC-GN-P01-PA1F:PSU3000-CON-SW = 0
    set signal EC-GN-P01-PB1F:PSU1000-CON-SW = 0
    set signal EC-GN-P01-PMF:PSU0000-CON-SW = 0
}
----------
2.
if (EC-GN-P01-GAF:STAT-BEAMON-TIME >= EC-GN-P01-GAF:STAT-DT-SHOTLEN)
{
    change state to HVArmed
}
----------
3.
  count up elapsed time (time from HVON detection)
  Write time to EC-GN-P01-GAF:STAT-ELAPSED
----------
4.
When enter the state beam-on timer is set to 0.
count up beam-on time. write the time into EC-GN-P01-GAF:STAT-BEAMON-TIME
----------



RFONESDN
==========
// TODO is this correct?
// MEMO: In the ESDN sync mode, HVPS turned off by ESDN packet.
// In both mode, there is mode_limit which is given by (EC-GN-P01-GPF:PLC4110-YTS-MD1,2,3,4).
1.
// This only executes on the last cycle before we move to HVArmed
if (EC-GN-P01-GAF:STAT-BEAMON-TIME >= t_mode_limit) // TODO: where do I get t_mode_limit?
{
    set signal EC-GN-P01-PA1F:PSU3000-CON-SW = 0
    set signal EC-GN-P01-PB1F:PSU1000-CON-SW = 0
    set signal EC-GN-P01-PMF:PSU0000-CON-SW = 0
}
----------
2.
if (EC-GN-P01-GAF:STAT-BEAMON-TIME >= t_mode_limit) // TODO: where do I get t_mode_limit?
{
    change state to HVArmedESDN
}
----------
3.
Subscribe ESDN commands. When GAM detect Beam-off command. It turn all HVPS SW OFF.
And change state to HVArmedESDN
----------
4.
  count up elapsed time (time from HVON detection)
  Write time to EC-GN-P01-GAF:STAT-ELAPSED
----------
5.
When enter the state beam-on timer is set to 0.
count up beam-on time. write the time into EC-GN-P01-GAF:STAT-BEAMON-TIME
----------


Error
==========
1.
// Only execute on the first cycle after entering this state
if (first)
{
    set first = false

    set signal EC-GN-P01-PA1F:PUS3000-CON-HV = 0 // TODO: there is no signal named EC-GN-P01-PA1F:PUS3000-CON-HV
    set signal EC-GN-P01-PA1F:PSU3000-CON-SW = 0
    set signal EC-GN-P01-PB1F:PSU1000-CON-HV = 0
    set signal EC-GN-P01-PB1F:PSU1000-CON-SW = 0
    set signal EC-GN-P01-PMF:PSU0000-CON-SW = 0
    // MEMO: PA2F and PB2F are component type for gyrotron B. I will remove following action.
    set signal EC-GN-P01-PA2F:PUS4000-CON-HV = 0 // TODO: there is no signal named EC-GN-P01-PA2F:PUS4000-CON-HV
    set signal EC-GN-P01-PA2F:PSU4000-CON-SW = 0 // TODO: signal EC-GN-P01-PA2F:PSU4000-CON-SW missing in configuration file
    set signal EC-GN-P01-PB2F:PSU2000-CON-HV = 0 // TODO: signal EC-GN-P01-PB2F:PSU2000-CON-HV missing in configuration file
    set signal EC-GN-P01-PB2F:PSU2000-CON-SW = 0 // TODO: signal EC-GN-P01-PB2F:PSU2000-CON-SW missing in configuration file

    set signal EC-GN-P01-PMF:PSU0000-CON-SW = 1
    set signal EC-GN-P01-PA1F:PSU3000-CTRP = 1
    set signal EC-GN-P01-PB1F:PSU1000-CTRP = 1
    // MEMO: PA2F and PB2F are component type for gyrotron B. I will remove following action.
    set signal EC-GN-P01-PA2F:PSU4000-CTRP = 1 // TODO: signal EC-GN-P01-PA2F:PSU4000-CTRP missing in configuration file
    set signal EC-GN-P01-PB2F:PSU1000-CTRP = 1 // TODO: there is no signal named EC-GN-P01-PB2F:PSU1000-CTRP
}
----------
2.
if (EC-GN-P01-GPF:STAT-RST-FLT == 1 && ) // TODO: when do we go to Offline state?
{
    change state to Offline
}
----------
