/*******************************************************************************/
/*        Description file for the carousel in standalone mode                 */
/*                                                                             */
/*******************************************************************************/


package carouselStandalone

import java.util.Properties;
import org.lsst.ccs.bootstrap.BootstrapResourceUtils;
import org.lsst.ccs.subsystems.fcs.*
import org.lsst.ccs.subsystems.fcs.singlefiltertest.*
import org.lsst.ccs.subsystems.fcs.common.*
import org.lsst.ccs.subsystems.fcs.drivers.*
import org.lsst.ccs.subsystems.fcs.simulation.*
import org.lsst.ccs.subsystems.fcs.testbench.*
import org.lsst.ccs.drivers.canopenjni.*
import org.lsst.ccs.drivers.canopenjni.rmi.*
import org.lsst.ccs.description.groovy.CCSBuilder

//************************************************************************//
// subsystem properties
// org.lsst.ccs.run.mode can be "simulation" or "hardware"
// org.lsst.ccs.fcs.instance.carousel can be "PROTO" or "FINAL"
//************************************************************************//
Properties props = BootstrapResourceUtils.getBootstrapSystemProperties();
def runMode = props.getProperty("org.lsst.ccs.run.mode", "simulation");
def instanceCA = props.getProperty("org.lsst.ccs.fcs.instance.carousel", "FINAL");
//************************************************************************//

/* 
 * carousel positions when a socket is at STANDBY
 * example : socket 1 is at STANDBY when carousel position is -204200
 * */
def standbyPositionSocket
if ("simulation".equals(runMode) || "PROTO".equals(instanceCA)) {
    standbyPositionSocket = [-204200,-1075906,-1948470,-2821074,-3694258] as int[]
} else if ("FINAL".equals(instanceCA)) {
    //define here FINAL standbyPositionSocket
    standbyPositionSocket = [4197000,707208,1579656,2452104,3324552] as int[]
}

/* numOfAnalogInput on the CANopen device where we read the clamps sensors*/
def numOfAnalogInputFilterPresenceSensorXminus = [1, 2, 3, 4, 5] as int[]
def numOfAnalogInputLockSensorXminus = [6, 7, 8, 9, 10] as int[]
def numOfAnalogInputFilterPresenceSensorXplus = [11, 12, 13, 14, 15] as int[]
def numOfAnalogInputLockSensorXplus = [16, 17, 18, 19, 20] as int[]

//Carousel Can Open Devices (CAN-CBX-AI814) for Carousel brakes status + brakes temperatures
def adcName = "ai814"

//Carousel CAN OPEN device to read carousel clamp sensors
def caTTC580Name = "hyttc580"

//Carousel clamps controllers name
def clampXminusControllerName = "clampXminusController" //controller to unlock clamp on the side Xminus
def clampXplusControllerName =  "clampXplusController" //controller to unlock clamp on the side Xplus

def plutoGatewayName = "$caTTC580Name" // to monitor the fake autochanger sensors

Class carouselClass = Class.forName("org.lsst.ccs.subsystems.fcs." + (runMode.equals("simulation") ? "simulation.Simu" : "") + "Carousel");

//decide which subsystem to launch depending on runMode and instanceCA
if ("simulation".equals(runMode)) {
    subsystemName = "carousel-standalone-simu"
} else if ("PROTO".equals(instanceCA)) {
    subsystemName = "carousel-standalone_PROTO"
} else {
    subsystemName = "carousel-standalone"
} 

CCSBuilder builder = [subsystemName]
builder.
    main ( CarouselMain, bridge:ref("tcpProxy"), autochanger:ref("autochanger")) 
{ //begin description of CarouselMain

    tcpProxy (CanOpenProxy, hardwareBootTimeout:2500) {
        
        //real hardware
        if ( "hardware".equals(runMode) && "FINAL".equals(instanceCA) ) {
            canInterface(CanOpenCommands, coi:new CanFestivalJNI());
            
            "$clampXminusControllerName" (CanOpenEPOSCarouselClamp,
                nodeID:0x1a, serialNB:"79029102")
        
            "$clampXplusControllerName" (CanOpenEPOSCarouselClamp,
                nodeID:0x1b, serialNB:"79028932")

            carouselController (CanOpenEPOSCarousel,
                nodeID:0xc, serialNB:"80012116")
            
            // can open devices to read clamps sensors
            "$caTTC580Name" (CanOpenTTC580, nodeID:0x3, serialNB:"25008180")
        
            // can open devices to read brakes sensors and temperatures
            "$adcName" (CanCBXAI814, nodeID:0x1e, serialNB:"c7c80479", transmissionType:1)
            
        } else if ( "hardware".equals(runMode) && "PROTO".equals(instanceCA) ) {
            canInterface(CanOpenCommands, coi:new CanFestivalJNI());
            
            "$clampXminusControllerName" (CanOpenEPOSCarouselClamp,
                nodeID:0x1a, serialNB:"79003900")
        
            "$clampXplusControllerName" (CanOpenEPOSCarouselClamp,
                nodeID:0x1b, serialNB:"79020968")

            carouselController (CanOpenEPOSCarousel,
                nodeID:0xc, serialNB:"80003117")
            
            // can open devices to read clamps sensors
            "$caTTC580Name" (CanOpenTTC580, nodeID:0x3, serialNB:"25008180")
        
            // can open devices to read brakes sensors and temperatures
            "$adcName" (CanCBXAI814, nodeID:0x1e, serialNB:"c7ca0645", transmissionType:1)            
        
        //Simulated CAN open devices
        } else {
            canInterface(SimuCanOpenInterface);
            
            "$clampXminusControllerName" (SimuCarouselClampController,
                nodeID:0x1a, serialNB:"79003317")
        
            "$clampXplusControllerName" (SimuCarouselClampController,
                nodeID:0x1b, serialNB:"79003313")
        
            carouselController (SimuCarouselController,
                nodeID:0xc, serialNB:"80003117")
            
            // can open devices to read clamps sensors
            "$caTTC580Name" (SimuTTC580, nodeID:0x3, serialNB:"25008180")
        
            // can open devices to read brakes sensors and temperatures
            "$adcName" (SimuCanOpenADC, nodeID:0x1e, serialNB:"c7ca0645", transmissionType:1)
            
            //fake plutoGateway to simulate autochanger signals
            fakePlutoGateway (SimuCarouselStandalonePlutoGateway, nodeID:0x99, serialNB:"999999")
        }
        
        // can open devices to read brakes sensors and temperatures
        pt100 (CanOpenDevice, nodeID:0x1f, serialNB:"c7c50149")  

    } //end of carousel's bridge hardware
    //**************************************************************************//
    // end of Bridge
    //**************************************************************************//
    //-------------------------
    // BEGIN Filter Manager description
    filterManager(FilterManager)
    {//begin description of filter manager's children
        filterU (Filter,filterID:29, weight:38)
        filterG (Filter,filterID:3, weight:33)
        filterR (Filter,filterID:60, weight:30)
        filterI (Filter,filterID:34, weight:28)
        filterZ (Filter,filterID:17, weight:28)
        filterY (Filter,filterID:15, weight:22.5)
        dummyFilter (Filter,filterID:46,weight:44.5)
    }//end description of filter manager's children
    // END Filter Manager description
    // ------------------------------
    


    /**********************************************************************/
    /*                BEGIN OF CAROUSEL DESCRIPTION                       */
    /**********************************************************************/
    
    

    //----------------------------
    // BEGIN Carousel description
    carousel(carouselClass)
    {//begin description of carousel's children
        /**********************************************************************/
        /*SOCKETi*/
        for (int i = 1; i<6;i++ ) {
            "socket${i}" ( CarouselSocket,
                id:i,
                clampXminus:ref("clampXminus${i}"),
                clampXplus:ref("clampXplus${i}"),
                standbyPosition: standbyPositionSocket[i-1],
                slaveModuleSensor:ref("slaveModuleSensor${i}")
            )
            {   
                "slaveModuleSensor${i}" (CarouselSensor, deviceName: caTTC580Name)
                //-------------------------
                // BEGIN clampXminus description
                "clampXminus${i}" (CarouselClamp,
                    filterPresenceSensor:ref("filterPresenceXminus${i}"),
                    lockSensor:ref("lockSensorXminus${i}"),
//                    thermometer:ref("thermometerXminus${i}")
                ) 
                {
                    "filterPresenceXminus${i}" (CarouselClampSensor, deviceName: caTTC580Name)
                    
                    "lockSensorXminus${i}" (CarouselClampSensor, deviceName: caTTC580Name) 
                    
//                    "thermometerXminus${i}" (Thermometer)
                }
                //-------------------------
                // END clampXminus description
                
                //-------------------------
                // BEGIN clampXplus description
                "clampXplus${i}" (CarouselClamp,
                    filterPresenceSensor:ref("filterPresenceXplus${i}"),
                    lockSensor:ref("lockSensorXplus${i}"),
//                    thermometer:ref("thermometerXplus${i}")
                )
                {
                    "filterPresenceXplus${i}" (CarouselClampSensor, deviceName:caTTC580Name)
                    "lockSensorXplus${i}" (CarouselClampSensor, deviceName:caTTC580Name)
//                    "thermometerXplus${i}" (Thermometer)
                }
                //-------------------------
                // END clampXplus description
            } // END carouselSocket /*SOCKETi*/ description
        } // END of loop of carouselSocket description.
        
        acAF3 (ComplementarySensors,
            sensor:ref("acAF3s"),
            sensorC:ref("acAF3b"),
        ) {
            acAF3s (DigitalSensor,
                dioName:"fakePlutoGateway", inputNumero:6, byteNumero:11)
            acAF3b (DigitalSensor,
                dioName:"fakePlutoGateway", inputNumero:7, byteNumero:11)
        }
    }//end description of carousel's children
    //END Carousel description
    // ------------------------
    /**********************************************************************/
    /*                FAKE AUTOCHANGER DESCRIPTION                       */
    /**********************************************************************/
    //in the carousel standalone subsystem the fake autochanger is a switch which
    //simulate that autochanger holds a filter at STANDBY 
    
    autochanger(FakeFilterHolder, holdingFilterSensorName:"acAF3s", notHoldingFilterSensorName:"acAF3b")

    /**********************************************************************/
    /*                END of FAKE AUTOCHANGER DESCRIPTION                 */
    /**********************************************************************/
} // end of CarouselMain description
