package fcs

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

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

def subsystemName
//decide which subsystem to launch depending on runMode, instanceAC and instanceLO
if ("simulation".equals(runMode)) {
    subsystemName = "fcs-simu"
} else {
    subsystemName = "fcs"
} 

def canopenProxyClass
if ("hardware".equals(runMode)) {
    canopenProxyClass = LoaderCanOpenProxy.class;
} else {
    canopenProxyClass = SimuLoaderCanOpenProxy.class;
}

CCSBuilder builder = [subsystemName]


//********************************************************************************//
//Carousel variables
//********************************************************************************//
/* 
 * carousel positions when a socket is at STANDBY
 * example : socket 1 is at STANDBY when carousel position is -204200
 * */
def standbyPositionSocket
if ("PROTO".equals(instanceCA)) {
    standbyPositionSocket = [-204220,-1076700,-1949180,-2821500,-3694040] as int[]
} else if ("FINAL".equals(instanceCA) || "simulation".equals(runMode)) {
    standbyPositionSocket = [4197000,3324500,2451800,1579700,707070] 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)
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
//********************************************************************************//

//********************************************************************************//
//Autochanger variables
//********************************************************************************//
def acPlutoGatewayName = "acSensorsGateway" // to monitor the autochanger sensors
//************************************************************************//
//In FINAL products AC1 and AC2 on linear rails, 
//truckX+  is controlled by master controller
//and truckX- is controlled by slave controller.
//On prototype truckX+ is controlled by slave and X- by master.
//************************************************************************//
def truckXminusControllerName
def truckXplusControllerName
if ("AC1".equals(instanceAC) || "AC2".equals(instanceAC)) {
    truckXminusControllerName = "linearRailSlaveController";
    truckXplusControllerName = "linearRailMasterController";
} else {
    truckXminusControllerName = "linearRailMasterController";
    truckXplusControllerName = "linearRailSlaveController";
}
//********************************************************************************//

//********************************************************************************//
//Loader variables
//********************************************************************************//
def bridgeToLoaderName = "loaderTcpProxy"
def loaderPlutoGatewayName = "loaderPlutoGateway" // to monitor the loader sensors
//********************************************************************************//

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

builder.
    main(org.lsst.ccs.subsystems.fcs.FcsMain,
    bridge:ref("tcpProxy"),   
    bridgeToLoader:ref("$bridgeToLoaderName"),
) { //begin description of Main subs
    
    //-------------------------
    // 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)
        filterID_46 (Filter,filterID:46,weight:44.5)
        filterID_40 (Filter, filterID:40, weight:38)
        filterID_30 (Filter, filterID:30, weight:38)
        filterID_27 (Filter, filterID:27, weight:31)
        filterID_5 (Filter, filterID:5, weight:26)
        filterID_54 (Filter, filterID:54, weight:26)
        
    }//end description of filter manager's children
    // END Filter Manager description
    // ------------------------------
    
    //-------------------------
    // tcp Proxy
    tcpProxy (CanOpenProxy, 
        canInterface:ref("canInterface")) 
    {
                
        //real hardware
        if ( runMode.equals("hardware")) {
        
//            //PC104 carousel
//            canInterface(CanOpenCommands, coi:new CanOpenRMIClient("134.158.153.195", "canbus0")) 
            //to launch fcs on the same HCU than canfestival
            canInterface(CanOpenCommands, coi:new CanFestivalJNI())
            
            // can open devices to read clamps sensors
            "$caTTC580Name" (CanOpenTTC580, nodeID:0x3, serialNB:"25008180")
            
            if ("PROTO".equals(instanceCA)) {
        
                //Carousel Hardware
                "$clampXminusControllerName" (CanOpenEPOSCarouselClamp,
                    nodeID:0x1a, serialNB:"79003900")

                "$clampXplusControllerName" (CanOpenEPOSCarouselClamp,
                    nodeID:0x1b, serialNB:"79020968")

                carouselController (CanOpenEPOSCarousel,
                    nodeID:0xc, serialNB:"80003117")
                
                "$adcName" (CanCBXAI814, nodeID:0x1e, serialNB:"c7ca0645", transmissionType:1) 
            
                // can open devices to read temperatures in carousel motor and brakes
                pt100 (CanOpenPT100, nodeID:0x1f, serialNB:"c7c50149")
            
            } else if ("FINAL".equals(instanceCA)) {
                
                //Carousel Hardware
                "$clampXminusControllerName" (CanOpenEPOSCarouselClamp,
                    nodeID:0x1a, serialNB:"79029102")

                "$clampXplusControllerName" (CanOpenEPOSCarouselClamp,
                    nodeID:0x1b, serialNB:"79028932")

                carouselController (CanOpenEPOSCarousel,
                    nodeID:0xc, serialNB:"80012116")

                // can open devices to read brakes sensors and temperatures
                "$adcName" (CanCBXAI814, nodeID:0x1e, serialNB:"c7c80479", transmissionType:1)

                // can open devices to read brakes sensors and temperatures
                pt100 (CanOpenPT100, nodeID:0x1f, serialNB:"c7c60186")
            }
            
            //PROTO autochanger
            if  ("PROTO".equals(instanceAC)) {

                // can open devices to read brakes sensors and temperatures
                "$adcName" (CanCBXAI814, nodeID:0x1e, serialNB:"c7ca0645", transmissionType:1) 

                // autochanger can open devices
                //sensors gateway
                "$acPlutoGatewayName" (CanOpenPlutoGateway, nodeID:0x3a,serialNB:"3269")

                onlineStrainGauge (CanOpenStrainGauge, nodeID: 0x21, serialNB:"0")

                // can open devices
                linearRailMasterController (CanOpenEPOSLinearRailTruck, 
                    nodeID:0x2a,serialNB:"80001881"
                )

                // can open devices
                linearRailSlaveController (CanOpenEPOSLinearRailTruck,
                    nodeID:0x2c,serialNB:"80008572"
                )     

                latchXminusController (CanOpenEPOS,  //CanOpenEPOS24-3
                    nodeID:0xf,serialNB:"84004735"
                )

                // can open devices
                latchXplusController (CanOpenEPOS,  //CanOpenEPOS24-3
                    nodeID:0xe, serialNB:"84004711"
                )

                // can open devices
                onlineClampXminusController (CanOpenEPOSOnlineClamp, 
                    nodeID:0x31,serialNB:"79011618"
                )
                // can open devices
                onlineClampXplusController (CanOpenEPOSOnlineClamp, 
                    nodeID:0x30, serialNB:"79011616"
                )
                // can open devices
                onlineClampYminusController (CanOpenEPOSOnlineClamp, 
                    nodeID:0x32, serialNB:"79011243"
                )
                brakeSystemGateway (CanOpenPlutoGateway, nodeID:0x2b,serialNB:"2071")
                tempSensorsDevice (CanOpenSystecIO, nodeID: 0x20, serialNB:"4bb6b")
                tempSensorsDevice1 (CanOpenSeneca4RTD, nodeID: 0x4a, serialNB:"4bb6b")
                tempSensorsDevice2 (CanOpenSeneca4RTD, nodeID: 0x4b, serialNB:"19VE0076")
            
            //final produit AC1
            } else if ("AC1".equals(instanceAC)) {
                // can open devices
                //sensors gateway
                "$acPlutoGatewayName" (CanOpenPlutoGateway, nodeID:0x3a,serialNB:"446b")

                onlineStrainGauge (CanOpenStrainGauge, nodeID: 0x21, serialNB:"0")
                // can open motor controllers
                linearRailMasterController (CanOpenEPOSLinearRailTruck, 
                    nodeID:0x2a,serialNB:"80011240",
                )

                // can open devices
                linearRailSlaveController (CanOpenEPOSLinearRailTruck,
                    nodeID:0x2c,serialNB:"80011011",
                )     

                latchXminusController (CanOpenEPOS,  //CanOpenEPOS24-3
                    nodeID:0xf,serialNB:"84010184",
                )

                // can open devices
                latchXplusController (CanOpenEPOS,  //CanOpenEPOS24-3
                    nodeID:0xe, serialNB:"84010169",
                )

                // can open devices
                onlineClampXminusController (CanOpenEPOSOnlineClamp, 
                    nodeID:0x31,serialNB:"79022208",
                )
                // can open devices
                onlineClampXplusController (CanOpenEPOSOnlineClamp, 
                    nodeID:0x30, serialNB:"79029101",
                )
                // can open devices
                onlineClampYminusController (CanOpenEPOSOnlineClamp, 
                    nodeID:0x32, serialNB:"79026482",
                )
                brakeSystemGateway (CanOpenPlutoGateway, nodeID:0x2b,serialNB:"4472")
                tempSensorsDevice1 (CanOpenSeneca4RTD, nodeID: 0x4a, serialNB:"19VE0077")
                tempSensorsDevice2 (CanOpenSeneca4RTD, nodeID: 0x4b, serialNB:"19VE0076")
                proximitySensorsDevice (CanCBXAI420, nodeID: 0x22, serialNB:"c7c60364")
                
            //end of description of autochanger AC1    
            } else if ("AC2".equals(instanceAC)) {
                // put here description of CANopen devices for AC2
            } //end of description of CANopen devices for autochanger AC2
        
        //simulated hardware
        } else {
            
            canInterface(SimuCanOpenInterface)      
            //Carousel controllers
            "$clampXminusControllerName" (SimuCarouselClampController,
                nodeID:0x1a,serialNB:"79003317")  

            "$clampXplusControllerName" (SimuCarouselClampController,
                nodeID:0x1b,serialNB:"79003313")

            carouselController (SimuCarouselController,
                nodeID:0xc,serialNB:"80003117")

            // can open devices to read carousel clamps sensors
            hyttc580 (SimuTTC580, nodeID:0x3, serialNB:"25008180")

            // can open devices to read carousel brakes sensors and temperatures
            ai814 (SimuCanOpenADC,nodeID:0x1e,serialNB:"c7yyyyyy",transmissionType:1)

            // can open devices to read carousel brakes sensors and temperatures
            pt100 (CanOpenPT100, nodeID:0x1f,serialNB:"c7zzzzzz")

            // autochanger can open devices
            //sensors gateway
            "$acPlutoGatewayName" (SimuAutochangerPlutoGateway,
                nodeID:0x6,serialNB:"3269")

            onlineStrainGauge (SimuCanOpenStrainGauge, nodeID: 0x21, serialNB:"0")

            linearRailMasterController (SimuAutochangerLinearRailController, 
                nodeID:0x2a, serialNB:"80001881",
                plutoGateway:ref("$acPlutoGatewayName")
            )

            // autochanger can open devices
            linearRailSlaveController (SimuAutochangerLinearRailController, 
                nodeID:0x2c,serialNB:"80001932",plutoGateway:ref("$acPlutoGatewayName"),
            )

            // autochanger can open devices   
            latchXminusController (SimuAutochangerLatchController,  //CanOpenEPOS24-3
                nodeID:0xf,serialNB:"84004711",latchName:"latchXminus",
                plutoGateway:ref("$acPlutoGatewayName"),
            )

            // autochanger can open devices
            latchXplusController (SimuAutochangerLatchController,  //CanOpenEPOS24-3
                nodeID:0xe,serialNB:"999XXXX",latchName:"latchXplus",
                plutoGateway:ref("$acPlutoGatewayName"),
            )

            // autochanger can open devices
            onlineClampXminusController (SimuAutochangerOnlineClampController, 
                nodeID:0x3a,serialNB:"79011616",
                plutoGateway:ref("$acPlutoGatewayName"),
                onlineClampName:"onlineClampXminus",
            )

            // autochanger can open devices
            onlineClampXplusController (SimuAutochangerOnlineClampController, 
                nodeID:0x3b,serialNB:"xxxx99999",
                plutoGateway:ref("$acPlutoGatewayName"),
                onlineClampName:"onlineClampXplus",
            )

            // autochanger can open devices
            onlineClampYminusController (SimuAutochangerOnlineClampController, 
                nodeID:0x3c,serialNB:"xxxx99999",
                plutoGateway:ref("$acPlutoGatewayName"),
                onlineClampName:"onlineClampYminus",
            )
            
            brakeSystemGateway (CanOpenPlutoGateway, nodeID:0x2b,serialNB:"4472")
            tempSensorsDevice1 (CanOpenSeneca4RTD, nodeID: 0x4a, serialNB:"xxxxx")
            tempSensorsDevice2 (CanOpenSeneca4RTD, nodeID: 0x4b, serialNB:"yyyyyy")
            proximitySensorsDevice (SimuCanCBXAI420, nodeID: 0x22, serialNB:"c7c60364")

        }
        
    }//end description of bridgeToChanger's children
    //----------------------------------------------
    // END Bridge To CHANGER description
    //----------------------------------------------                
    //
    // tcp Proxy
    "$bridgeToLoaderName"(LoaderCanOpenProxy, 
        canInterface:ref("loaderCanInterface")) 
    {
        
        //real hardware
        if ( "hardware".equals(runMode) && "PROTO".equals(instanceLO)) {
            //baie du loader
            loaderCanInterface(CanOpenCommands, coi:new CanOpenRMIClient("134.158.155.194", "canbus1"))

            "$loaderPlutoGatewayName" (CanOpenPlutoGateway, nodeID:5,serialNB:"22d6")

            hooksController (CanOpenEPOS, nodeID:0x5b,serialNB:"79007141") 

            carrierController (CanOpenEPOS,nodeID:0x5a,serialNB:"80003184")
            
        } else if ("hardware".equals(runMode) && "LO1".equals(instanceLO)) {
            
            //test in January 2020 the following line doesn't work because an init of loaderCanInterface init the cahnger canInterface.
//            loaderCanInterface(CanOpenCommands, coi:new CanFestivalJNI())
            loaderCanInterface(CanOpenCommands, coi:new CanOpenRMIClient("134.79.209.94", "canbus1"))

            "$loaderPlutoGatewayName" (CanOpenPlutoGateway, nodeID:0x5, serialNB:"310f")
            
            // can open devices
            hooksController (CanOpenEPOS, nodeID:0x5b, serialNB:"79018738") 

            carrierController (CanOpenEPOS, nodeID:0x5a, serialNB:"80006442")
            
        } else if ("hardware".equals(runMode) && "LO2".equals(instanceLO)) {
            //put here description of LO2 CANopen devices
            
        //simulated hardware    
        } else {
            loaderCanInterface(SimuCanOpenInterface)
            
            // description of plutoGateway
            "$loaderPlutoGatewayName" (SimuLoaderStandalonePlutoGateway, 
                nodeID:1,serialNB:"22d6")

            hooksController (SimuLoaderClampController,
                nodeID:0x1b,serialNB:"79007141",
                plutoGateway:ref("$loaderPlutoGatewayName")) 

            carrierController (SimuLoaderCarrierController,
                nodeID:0x1a,serialNB:"80003184",
                plutoGateway:ref("$loaderPlutoGatewayName"))
            
        }


    }//end description of bridge's childrens
    //----------------------------------------------
    // END Bridge To LOADER description
    //---------------------------------------------
    
    
    // BEGIN Filter Identificator description
    filterIdentificator(FilterIdentificator)
    {//begin description of filter Identificator's children
        filterIDSensor0 ( DigitalSensor,
            dioName:acPlutoGatewayName,inputNumero:0,byteNumero:4)
        
        filterIDSensor1 ( DigitalSensor,
            dioName:acPlutoGatewayName,inputNumero:1,byteNumero:4)
        
        filterIDSensor2 ( DigitalSensor,
            dioName:acPlutoGatewayName,inputNumero:2,byteNumero:4)
        
        filterIDSensor3 ( DigitalSensor,
            dioName:acPlutoGatewayName,inputNumero:3,byteNumero:4)
        
        filterIDSensor4 ( DigitalSensor,
            dioName:acPlutoGatewayName,inputNumero:4,byteNumero:4)
        
        filterIDSensor5 ( DigitalSensor,
            dioName:acPlutoGatewayName,inputNumero:5,byteNumero:4)
    }//end description of filter identificator's children
    // END Filter Identificator 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}" ( carouselSocketClass,
                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.
        
    }//end description of carousel's children
    //END Carousel description
    // ------------------------    
    
    // ------ Monitoring 
    seneca1(TempMonitorDevice, tempSensorsDevice:ref("tempSensorsDevice1"))
    seneca2(TempMonitorDevice, tempSensorsDevice:ref("tempSensorsDevice2"))
    
    // Channels read as a group with getADCValues
    tempLinearRailMotorXplus(Channel, devcName:"seneca1", hwChan:1, units:"\u00b0C", format:".1f", type:"C", subtype:"", checkLo:"flag", limitLo:-20.0, alarmLo:null, checkHi:"flag", limitHi:100.0, alarmHi:null)
    tempLinearRailMotorXminus(Channel, devcName:"seneca1", hwChan:2, units:"\u00b0C", format:".1f", type:"C", subtype:"", checkLo:"flag", limitLo:-20.0, alarmLo:null, checkHi:"flag", limitHi:100.0, alarmHi:null)
    tempClampMotorXplus(Channel, devcName:"seneca1", hwChan:3, units:"\u00b0C", format:".1f", type:"C", subtype:"", checkLo:"flag", limitLo:-20.0, alarmLo:null, checkHi:"flag", limitHi:100.0, alarmHi:null)
    tempClampMotorYminus(Channel, devcName:"seneca1", hwChan:4, units:"\u00b0C", format:".1f", type:"C", subtype:"", checkLo:"flag", limitLo:-20.0, alarmLo:null, checkHi:"flag", limitHi:100.0, alarmHi:null)
    tempClampMotorXminus(Channel, devcName:"seneca2", hwChan:5, units:"\u00b0C", format:".1f", type:"C", subtype:"", checkLo:"flag", limitLo:-20.0, alarmLo:null, checkHi:"flag", limitHi:100.0, alarmHi:null)
    tempFrontBox(Channel, devcName:"seneca2", hwChan:6, units:"\u00b0C", format:".1f", type:"C", subtype:"", checkLo:"flag", limitLo:-20.0, alarmLo:null, checkHi:"flag", limitHi:100.0, alarmHi:null)
    tempRearBox(Channel, devcName:"seneca2", hwChan:7, units:"\u00b0C", format:".1f", type:"C", subtype:"", checkLo:"flag", limitLo:-20.0, alarmLo:null, checkHi:"flag", limitHi:100.0, alarmHi:null)
    tempCellXminus(Channel, devcName:"seneca2", hwChan:8, units:"\u00b0C", format:".1f", type:"C", subtype:"", checkLo:"flag", limitLo:-20.0, alarmLo:null, checkHi:"flag", limitHi:100.0, alarmHi:null)

    // ***************************
    // * LOCAL PROTECTION SYSTEM *
    // ***************************

    //Carousel_CFC signal read on AC pluto Gateway sent by carousel.
    carouselHoldingFilterSensors(ComplementarySensors,
        sensor:ref("carouselHoldingFilterSensor0"),
        sensorC:ref("carouselHoldingFilterSensor1")) {		
            carouselHoldingFilterSensor0(DigitalSensor ,		
                dioName:acPlutoGatewayName, inputNumero:6,byteNumero:3)		
            carouselHoldingFilterSensor1(DigitalSensor ,		
                dioName:acPlutoGatewayName, inputNumero:7,byteNumero:3)		
    }
        
    //Signals read on AC pluto gateway sent by loader
    // 
    loaderHoldingFilterSensors(ComplementarySensors, //Loader_LRH (ex LFL)
        sensor:ref("loaderHoldingFilterSensor0"),
        sensorC:ref("loaderHoldingFilterSensor1")) {		
            loaderHoldingFilterSensor0(DigitalSensor ,		
                dioName:acPlutoGatewayName, inputNumero:6, byteNumero:2)		
            loaderHoldingFilterSensor1(DigitalSensor ,		
                dioName:acPlutoGatewayName, inputNumero:7, byteNumero:2)    		
    }

    loaderConnectedSensors(ComplementarySensors, // Loader_LPS
        sensor:ref("loaderConnectedSensor"),
        sensorC:ref("loaderConnectedSensorC")) {
            loaderConnectedSensor(DigitalSensor ,		
                dioName:acPlutoGatewayName, inputNumero:4, byteNumero:2)		
            loaderConnectedSensorC(DigitalSensor ,		
                dioName:acPlutoGatewayName, inputNumero:5, byteNumero:2)		
    }//end description of autochanger loaderConnectedSensors children

    //Carousel_CS
    carouselStoppedAtStandbySensors(ComplementarySensors, // Carousel_CS
        sensor:ref("carouselStoppedAtStandby"),
        sensorC:ref("carouselStoppedAtStandbyC")) {
            carouselStoppedAtStandby(DigitalSensor,
                dioName:acPlutoGatewayName, inputNumero:0, byteNumero:3)		
            carouselStoppedAtStandbyC(DigitalSensor ,		
                dioName:acPlutoGatewayName, inputNumero:1, byteNumero:3)
    }//end description of autochanger carouselStoppedAtStandbySensors children
    
    carousel_CF0Sensors(ComplementarySensors, // Carousel_CF0
        sensor:ref("carousel_CF0"),
        sensorC:ref("carousel_CF0_C")) {
            carousel_CF0(DigitalSensor,
                dioName:acPlutoGatewayName, inputNumero:2, byteNumero:3)		
            carousel_CF0_C(DigitalSensor ,		
                dioName:acPlutoGatewayName, inputNumero:3, byteNumero:3)
    }//end description of autochanger carousel_CF0 children 
    
    carousel_CF1Sensors(ComplementarySensors, // Carousel_CF1
        sensor:ref("carousel_CF1"),
        sensorC:ref("carousel_CF1_C")) {
            carousel_CF1(DigitalSensor,
                dioName:acPlutoGatewayName, inputNumero:4, byteNumero:3)		
            carousel_CF1_C(DigitalSensor ,		
                dioName:acPlutoGatewayName, inputNumero:5, byteNumero:3)
    }//end description of autochanger carousel_CF1 children 
    
            
    // Local Protection Module status
    lpmLinearRail1Status(DigitalSensor,
            dioName:acPlutoGatewayName, inputNumero:6, byteNumero:4) 
        
    lpmLinearRail2Status(DigitalSensor,
            dioName:acPlutoGatewayName, inputNumero:7, byteNumero:4)        
        
    lpmOnlineClampsStatus(DigitalSensor,
            dioName:acPlutoGatewayName, inputNumero:0, byteNumero:5)
        
    lpmLatchesStatus(DigitalSensor,
            dioName:acPlutoGatewayName, inputNumero:1, byteNumero:5)
        
    //loaderPresenceSensors is only on AC1 and AC2, not on PROTO
    loaderPresenceSensors ( ComplementarySensors,
                sensor:ref("presenceLoader"),
        sensorC:ref("presenceLoader_C")) {
            presenceLoader (DigitalSensor,
                dioName:acPlutoGatewayName, inputNumero:0, byteNumero:14)
            presenceLoader_C ( DigitalSensor,		
                dioName:acPlutoGatewayName, inputNumero:1, byteNumero:14)
    } // end description loaderPresenceSensors
    
    //lockOutSensors is only on AC1 and AC2, not on PROTO
    lockOutSensors ( ComplementarySensors,
                sensor:ref("lockOut"),
        sensorC:ref("lockOut_C")) {
            lockOut (DigitalSensor,
                dioName:acPlutoGatewayName, inputNumero:2, byteNumero:14)	
            lockOut_C ( DigitalSensor,
                dioName:acPlutoGatewayName, inputNumero:3, byteNumero:14)
    } // end description lockOutSensors 
    
    //Signal emitted by autochanger OUT_AF0
    OUT_AF0_Sensors ( ComplementarySensors,
        sensor:ref("OUT_AF0"),
        sensorC:ref("OUT_AF0_C")) {
            OUT_AF0 (DigitalSensor,
                dioName:acPlutoGatewayName, inputNumero:4, byteNumero:10)		
            OUT_AF0_C ( DigitalSensor,		
                dioName:acPlutoGatewayName, inputNumero:5, byteNumero:10)
    } // end description OUT_AF0      

    //Signal emitted by autochanger OUT_AF1
    OUT_AF1_Sensors ( ComplementarySensors,
        sensor:ref("OUT_AF1"),
        sensorC:ref("OUT_AF1_C")) {
            OUT_AF1 (DigitalSensor,
                dioName:acPlutoGatewayName, inputNumero:6, byteNumero:10)		
            OUT_AF1_C ( DigitalSensor,		
                dioName:acPlutoGatewayName, inputNumero:7, byteNumero:10)
    } // end description OUT_AF1     
    
    //Signal emitted by autochanger OUT_AF3
    OUT_AF3_Sensors ( ComplementarySensors,
        sensor:ref("OUT_AF3"),
        sensorC:ref("OUT_AF3_C")) {
            OUT_AF3 (DigitalSensor,
                dioName:acPlutoGatewayName, inputNumero:0, byteNumero:11)		
            OUT_AF3_C ( DigitalSensor,		
                dioName:acPlutoGatewayName, inputNumero:1, byteNumero:11)
    } // end description OUT_AF3    

    //Signal emitted by autochanger OUT_AP1
    OUT_AP1_Sensors ( ComplementarySensors,
        sensor:ref("OUT_AP1"),
        sensorC:ref("OUT_AP1_C")) {
            OUT_AP1 (DigitalSensor,
                dioName:acPlutoGatewayName, inputNumero:6, byteNumero:11)		
            OUT_AP1_C ( DigitalSensor,		
                dioName:acPlutoGatewayName, inputNumero:7, byteNumero:11)
    } // end description OUT_AP1 
    
    //Signal emitted by autochanger OUT_AP2
    OUT_AP2_Sensors ( ComplementarySensors,
        sensor:ref("OUT_AP2"),
        sensorC:ref("OUT_AP2_C")) {
            OUT_AP2 (DigitalSensor,
                dioName:acPlutoGatewayName, inputNumero:2, byteNumero:11)		
            OUT_AP2_C ( DigitalSensor,		
                dioName:acPlutoGatewayName, inputNumero:3, byteNumero:11)
    } // end description OUT_AP2
    
    //Signal emitted by autochanger OUT_AP3
    OUT_AP3_Sensors ( ComplementarySensors,
        sensor:ref("OUT_AP3"),
        sensorC:ref("OUT_AP3_C")) {
            OUT_AP3 (DigitalSensor,
                dioName:acPlutoGatewayName, inputNumero:4, byteNumero:11)		
            OUT_AP3_C ( DigitalSensor,		
                dioName:acPlutoGatewayName, inputNumero:5, byteNumero:11)
    } // end description OUT_AP3  
        
    //**************************************************************************//
    //**************************************************************************//
    // autochanger
    //**************************************************************************//
    //**************************************************************************//
    autochanger(autochangerClass, plutoGateway:ref("$acPlutoGatewayName")) {
        ////begin description of autochanger children
        
        //**************************************************************************//
        // autochanger trucks description
        //**************************************************************************//
        autochangerTrucks (AutochangerTwoTrucks, 
            truckXminus:ref("acTruckXminus"), truckXplus:ref("acTruckXplus"),
            linearRailMasterController:ref("linearRailMasterController"),
            linearRailSlaveController:ref("linearRailSlaveController")) {
            //begin description of autochanger trucks children
            acTruckXminus (AutochangerTruck, 
                controller:ref("$truckXminusControllerName"),
                handoffPositionSensors:ref("handoffPositionSensorsXminus"),
                onlinePositionSensors:ref("onlinePositionSensorsXminus"),
                standbyPositionSensors:ref("standbyPositionSensorsXminus"),
            )
            {//begin description of autochanger truckXminus children
                handoffPositionSensorsXminus ( ComplementarySensors,
                    sensor: ref("handoffPositionSensorXminus"),
                    sensorC: ref("handoffPositionSensorBXminus"),
                )
                {
                    handoffPositionSensorXminus ( DigitalSensor ,
                        dioName:acPlutoGatewayName, inputNumero:0, byteNumero:1)
                    
                    handoffPositionSensorBXminus ( DigitalSensor ,
                        dioName:acPlutoGatewayName, inputNumero:1, byteNumero:1)
                }
                onlinePositionSensorsXminus ( ComplementarySensors,
                    sensor: ref("onlinePositionSensorXminus"),
                    sensorC: ref("onlinePositionSensorBXminus"),
                )
                {
                    onlinePositionSensorXminus ( DigitalSensor ,
                        dioName:acPlutoGatewayName, inputNumero:2, byteNumero:1)
                    
                    onlinePositionSensorBXminus ( DigitalSensor ,
                        dioName:acPlutoGatewayName,inputNumero:3, byteNumero:1)
                }
                standbyPositionSensorsXminus ( ComplementarySensors,
                    sensor: ref("standbyPositionSensorXminus"),
                    sensorC: ref("standbyPositionSensorBXminus"),
                )
                {
                    standbyPositionSensorXminus ( DigitalSensor ,
                        dioName:acPlutoGatewayName, inputNumero:6, byteNumero:0)
                    
                    standbyPositionSensorBXminus ( DigitalSensor ,
                        dioName:acPlutoGatewayName, inputNumero:7, byteNumero:0)
                }
            }//end description of autochanger acTruckXminus children
            acTruckXplus (AutochangerTruck, 
                controller:ref("$truckXplusControllerName"),
                handoffPositionSensors:ref("handoffPositionSensorsXplus"),
                onlinePositionSensors:ref("onlinePositionSensorsXplus"),
                standbyPositionSensors:ref("standbyPositionSensorsXplus"),
            )
            {//begin description of autochanger truckXplus children
                handoffPositionSensorsXplus (ComplementarySensors,
                     sensor: ref("handoffPositionSensorXplus"),
                     sensorC: ref("handoffPositionSensorBXplus"),
                 )
                 {
                     handoffPositionSensorXplus ( DigitalSensor ,
                         dioName:acPlutoGatewayName, inputNumero: 0, byteNumero:9)                                    
                     handoffPositionSensorBXplus ( DigitalSensor ,
                         dioName:acPlutoGatewayName, inputNumero:1, byteNumero:9)
                 }
                 onlinePositionSensorsXplus (ComplementarySensors,
                     sensor: ref("onlinePositionSensorXplus"),
                     sensorC: ref("onlinePositionSensorBXplus"),
                 )
                 {
                     onlinePositionSensorXplus ( DigitalSensor ,
                         dioName:acPlutoGatewayName, inputNumero:2, byteNumero:9)
                     onlinePositionSensorBXplus ( DigitalSensor ,
                         dioName:acPlutoGatewayName, inputNumero:3, byteNumero:9)
                 }
                 standbyPositionSensorsXplus (ComplementarySensors,
                     sensor: ref("standbyPositionSensorXplus"),
                     sensorC: ref("standbyPositionSensorBXplus"),
                 )
                 {
                     standbyPositionSensorXplus( DigitalSensor ,
                         dioName:acPlutoGatewayName, inputNumero:6, byteNumero:8)
                     standbyPositionSensorBXplus ( DigitalSensor ,
                         dioName:acPlutoGatewayName, inputNumero:7, byteNumero:8)
                 }
            }//end description of autochanger acTruckXplus children
            
        }//end description of autochanger trucks children            
        //**************************************************************************//
        // end of autochanger trucks description
        //**************************************************************************//
        
        //**************************************************************************//
        // autochanger latches description
        //**************************************************************************//
        latches (AutochangerTwoLatches, latchXminus:ref("latchXminus"), latchXplus:ref("latchXplus"))
        {//begin description of autochanger latches children
            //*************************************//
            // autochanger latchXminus description
            //*************************************//
            latchXminus (AutochangerLatch,
                latchController:ref("latchXminusController"),
                closeSensors:ref("closeSensorsLatchXminus"),
                openSensors:ref("openSensorsLatchXminus"),
                filterEngagedSensors:ref("filterEngagedSensorsLatchXminus"),
            )
            {//begin description of autochanger latchXminus children
                closeSensorsLatchXminus ( ComplementarySensors,
                    sensor:ref("closeSensorLatchXminus"),
                    sensorC:ref("closeSensorBLatchXminus")
                )
                {//begin description of autochanger lockSensorslatchXminus children
                    closeSensorLatchXminus ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero:0, byteNumero:0)
                    closeSensorBLatchXminus ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero:1, byteNumero:0)
                }//end description of autochanger lockSensorslatchXminus children                
                
                openSensorsLatchXminus ( ComplementarySensors,
                    sensor:ref("openSensorLatchXminus"),
                    sensorC:ref("openSensorBLatchXminus")
                ) {//begin description of autochanger unlockSensorslatchXminus children
                    openSensorLatchXminus ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero:2, byteNumero:0)
                    openSensorBLatchXminus ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero:3, byteNumero:0)
                }//end description of autochanger unlockSensorslatchXminus children
                
                filterEngagedSensorsLatchXminus ( ComplementarySensors,
                    sensor:ref("filterEngagedSensorLatchXminus"),
                    sensorC:ref("filterEngagedSensorBLatchXminus")
                )
                {//begin description of autochanger filterEngagedSensorslatchXminus children
                    filterEngagedSensorLatchXminus ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero:4, byteNumero:0)
                    filterEngagedSensorBLatchXminus ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero:5, byteNumero:0)
                }//end description of autochanger filterEngagedSensorslatchXminus children
            }//end description of autochanger latchXminus children
            //**********************************************//
            // end of autochanger latchXminus description   //
            //**********************************************//
            //*************************************//
            // autochanger latchXplus description
            //*************************************//
            latchXplus (AutochangerLatch,
                latchController:ref("latchXplusController"),
                closeSensors:ref("closeSensorsLatchXplus"),
                openSensors:ref("openSensorsLatchXplus"),
                filterEngagedSensors:ref("filterEngagedSensorsLatchXplus"),
            )
            {//begin description of autochanger latchXplus children

                closeSensorsLatchXplus ( ComplementarySensors,
                    sensor:ref("closeSensorLatchXplus"),
                    sensorC:ref("closeSensorBLatchXplus")
                )
                {//begin description of autochanger lockSensorslatchXplus children
                    closeSensorLatchXplus ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero:0, byteNumero:8)
                    closeSensorBLatchXplus ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero:1, byteNumero:8)
                }//end description of autochanger lockSensorslatchXplus children
                openSensorsLatchXplus ( ComplementarySensors,
                     sensor:ref("openSensorLatchXplus"),
                     sensorC:ref("openSensorBLatchXplus")
                 )     
                 {//begin description of autochanger unlockSensorslatchXplus children
                     openSensorLatchXplus ( DigitalSensor,
                         dioName:acPlutoGatewayName, inputNumero:2, byteNumero:8)
                     openSensorBLatchXplus ( DigitalSensor,
                         dioName:acPlutoGatewayName, inputNumero:3, byteNumero:8)
                 }//end description of autochanger unlockSensorslatchXplus children
 
                 filterEngagedSensorsLatchXplus ( ComplementarySensors,
                     sensor:ref("filterEngagedSensorLatchXplus"),
                     sensorC:ref("filterEngagedSensorBLatchXplus")
                 )
                 {//begin description of autochanger filterEngagedSensorslatchXplus children
                     filterEngagedSensorLatchXplus ( DigitalSensor,
                         dioName:acPlutoGatewayName, inputNumero:4, byteNumero:8)
                     filterEngagedSensorBLatchXplus ( DigitalSensor,
                         dioName:acPlutoGatewayName, inputNumero:5, byteNumero:8)
                }//end description of autochanger filterEngagedSensorslatchXplus children

            }//end description of autochanger latchXplus children
            //**********************************************//
            // end of autochanger latchXplus description   //
            //**********************************************//
        }//end description of autochanger latches children
        //*****************************************************************************//
        // end of autochanger latches description
        //*****************************************************************************//
        
        //**************************************************************************//
        //**************************************************************************//
        // autochanger onlineClamps description
        //**************************************************************************//
        //**************************************************************************//
        onlineClamps (AutochangerThreeOnlineClamps, 
            onlineClampXminus:ref("onlineClampXminus"), 
            onlineClampXplus:ref("onlineClampXplus"), 
            onlineClampYminus:ref("onlineClampYminus")) 
        {//begin description of autochanger onlineClamps children
            
            onlineClampXminus(AutochangerOnlineClamp ,
                controller:ref("onlineClampXminusController"),
                closeSensors:ref("onlineClampXminusCloseSensors"),
                openSensors:ref("onlineClampXminusOpenSensors"),
            )
            {//begin description of autochanger onlineClampXminus children
                onlineClampXminusCloseSensors ( ComplementarySensors,
                    sensor:ref("onlineClampXminusCloseSensor"),
                    sensorC:ref("onlineClampXminusCloseSensorC")
                )
                {//begin description of autochanger onlineClampXminusCloseSensors children
                    onlineClampXminusCloseSensor ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero:6, byteNumero:1)
                    onlineClampXminusCloseSensorC ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero:7, byteNumero:1)
                }//end description of autochanger onlineClampXminusCloseSensors children
                
                onlineClampXminusOpenSensors ( ComplementarySensors,
                    sensor: ref("onlineClampXminusOpenSensor"),
                    sensorC: ref("onlineClampXminusOpenSensorC")
                )
                {
                    onlineClampXminusOpenSensor ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero: 4, byteNumero:1)
                    onlineClampXminusOpenSensorC ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero: 5, byteNumero:1)  
                }
            }//end of  description of autochanger onlineClampXminus children
            
            onlineClampXplus(AutochangerOnlineClamp ,
                controller:ref("onlineClampXplusController"),
                closeSensors:ref("onlineClampXplusCloseSensors"),
                openSensors:ref("onlineClampXplusOpenSensors"),
            )
            {//begin description of autochanger onlineClampXplus children
                onlineClampXplusCloseSensors ( ComplementarySensors,
                    sensor: ref("onlineClampXplusCloseSensor"),
                    sensorC: ref("onlineClampXplusCloseSensorC"),
                )
                {
                    onlineClampXplusCloseSensor ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero: 6, byteNumero: 9)
                    onlineClampXplusCloseSensorC ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero: 7, byteNumero: 9)
                }
                
                onlineClampXplusOpenSensors ( ComplementarySensors,
                    sensor: ref("onlineClampXplusOpenSensor"),
                    sensorC: ref("onlineClampXplusOpenSensorC"),
                )
                {
                    onlineClampXplusOpenSensor ( DigitalSensor,
                        dioName:acPlutoGatewayName,inputNumero: 4, byteNumero: 9)
                    onlineClampXplusOpenSensorC ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero: 5, byteNumero: 9)
                }
            }//end of  description of autochanger onlineClampXplus children
            
            onlineClampYminus(AutochangerOnlineClamp ,
                controller:ref("onlineClampYminusController"),
                closeSensors:ref("onlineClampYminusCloseSensors"),
                openSensors:ref("onlineClampYminusOpenSensors"),
            )
            {//begin description of autochanger onlineClampYminus children
                onlineClampYminusCloseSensors ( ComplementarySensors,
                    sensor: ref("onlineClampYminusCloseSensor"),
                    sensorC: ref("onlineClampYminusCloseSensorC"),
                )
                {
                    onlineClampYminusCloseSensor ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero: 2, byteNumero: 2)
                    onlineClampYminusCloseSensorC ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero: 3, byteNumero: 2)
                }
                onlineClampYminusOpenSensors ( ComplementarySensors,
                    sensor: ref("onlineClampYminusOpenSensor"),
                    sensorC: ref("onlineClampYminusOpenSensorC"),
                )
                {
                    onlineClampYminusOpenSensor ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero: 0, byteNumero: 2)
                    onlineClampYminusOpenSensorC ( DigitalSensor,
                        dioName:acPlutoGatewayName, inputNumero: 1, byteNumero: 2)
                }
            }//end of  description of autochanger onlineClampYminus children
        }//end of  description of autochanger onlineClamps children
        //**************************************************************************//
        // end of autochanger onlineClamps description
        //**************************************************************************//
        inclinometerXminus (Inclinometer, deviceName:acPlutoGatewayName, byteNumero: 6)
        inclinometerXplus (Inclinometer, deviceName:acPlutoGatewayName, byteNumero: 12)


    }//end description of autochanger children
    //*****************************************************************************//
    //*****************************************************************************//
    // end of autochanger description
    //*****************************************************************************//
    //*****************************************************************************//
    //begin description of loader
    loader (Loader)
    {//begin description of loader's children

        carrier(LoaderCarrier,
            handoffSensors:ref("loaderHandoffSensors"),
            storageSensors:ref("loaderStorageSensors"),
            engagedSensors:ref("loaderEngagedSensors")
        )
        {//begin description of loader carrier's children
            loaderEngagedSensors (RedondantSensors,
                sensor:ref("loaderEngagedPositionSensor0"), 
                sensorR: ref("loaderEngagedPositionSensor1")
            )
            {//begin description of loader engagedSensors
                loaderEngagedPositionSensor0 ( DigitalSensor ,
                    dioName:loaderPlutoGatewayName,inputNumero:6,byteNumero:3)

                loaderEngagedPositionSensor1 ( DigitalSensor ,
                    dioName:loaderPlutoGatewayName,inputNumero:7,byteNumero:3)
            }//end description of loader engagedSensors
            loaderHandoffSensors (RedondantSensors,
                sensor:ref("loaderHandoffPositionSensor0"), 
                sensorR: ref("loaderHandoffPositionSensor1")
            )
            {//begin description of loader handoffSensors
                loaderHandoffPositionSensor0 ( DigitalSensor ,
                    dioName:loaderPlutoGatewayName,inputNumero:0,byteNumero:6)

                loaderHandoffPositionSensor1 ( DigitalSensor ,
                    dioName:loaderPlutoGatewayName,inputNumero:1,byteNumero:6)
            }//end description of loader handoffSensors
            
            loaderStorageSensors (RedondantSensors,
                sensor:ref("loaderStoragePositionSensor0"),
                sensorR:ref("loaderStoragePositionSensor1"),
            )
            {//begin description of loader storageSensors
                //user_to_gateway n° 1
                loaderStoragePositionSensor0 ( DigitalSensor ,
                    dioName:loaderPlutoGatewayName, inputNumero:4,byteNumero:3)

                loaderStoragePositionSensor1 ( DigitalSensor ,
                    dioName:loaderPlutoGatewayName, inputNumero:5, byteNumero:3)  
            }//end description of loader storageSensors
        }//end description of loader carrier's children

        clamp(LoaderClamp,
            hook1:ref("hook1"),hook2:ref("hook2"), hook3:ref("hook3"),hook4:ref("hook4"),
            forceSensor0:ref("forceSensor0"), forceSensor1:ref("forceSensor1"),
            clampedStatusSensor: ref("clampedStatusSensor"),
            )
        {//begin description of loader clamp's children
            int[] inputNumeroClose = [4,5,6,7];
            int[] inputNumeroOpen = [0,1,2,3];
            for (int i = 1; i<5; i++) {
            
            "hook${i}"(LoaderHook,
                    closeSensor:ref("loaderCloseSensor${i}"), openSensor:ref("loaderOpenSensor${i}"))
                { //user_to_gateway n° 1
                    "loaderCloseSensor${i}" ( DigitalSensor , //closeHookSensor0
                        dioName:loaderPlutoGatewayName, inputNumero:inputNumeroClose[i-1], byteNumero:2)
                       
                    "loaderOpenSensor${i}" ( DigitalSensor , //openHookSensor0
                        dioName:loaderPlutoGatewayName, inputNumero:inputNumeroOpen[i-1], byteNumero:2)
                }
            }
            
            forceSensor0(ForceSensor, deviceName:loaderPlutoGatewayName, byteNumero:4)
            
            forceSensor1(ForceSensor, deviceName:loaderPlutoGatewayName, byteNumero:8)

            // user_to_gateway n° 2
            unclampedStatusSensor ( DigitalSensor ,
                dioName:loaderPlutoGatewayName,inputNumero:2,byteNumero:6)
            
            underClampedStatusSensor ( DigitalSensor ,
                dioName:loaderPlutoGatewayName,inputNumero:3,byteNumero:6)
            
            clampedStatusSensor ( DigitalSensor ,
                dioName:loaderPlutoGatewayName,inputNumero:4,byteNumero:6) 
            
            overClampedStatusSensor ( DigitalSensor ,
                dioName:loaderPlutoGatewayName,inputNumero:5,byteNumero:6)
        
        }//end description of loader clamp's children

       
        loaderFilterPresenceSensors (RedondantSensors,
            sensor:ref("loaderFilterPresenceSensor0"),
            sensorR:ref("loaderFilterPresenceSensor1"),
        )
        { // user_to_gateway n° 1
            loaderFilterPresenceSensor0(DigitalSensor ,
                dioName:loaderPlutoGatewayName,inputNumero:0, byteNumero:3)

            loaderFilterPresenceSensor1(DigitalSensor ,
                dioName:loaderPlutoGatewayName, inputNumero:1, byteNumero:3) 
        }

        loaderOnCameraSensors (RedondantSensors,
            sensor:ref("loaderOnCameraSensor0"),
            sensorR:ref("loaderOnCameraSensor1"),
        )
        { // user_to_gateway n° 1
            loaderOnCameraSensor0(DigitalSensor ,
                dioName:loaderPlutoGatewayName, inputNumero:2, byteNumero:3)

            loaderOnCameraSensor1(DigitalSensor ,
                dioName:loaderPlutoGatewayName, inputNumero:3, byteNumero:3)
        }
        
        loaderCarrierRelayStatus ( DigitalSensor ,
            dioName:loaderPlutoGatewayName,inputNumero:6,byteNumero:6)

        loaderHooksRelayStatus ( DigitalSensor ,
            dioName:loaderPlutoGatewayName,inputNumero:7,byteNumero:6)

        loaderChainPresenceSensor ( DigitalSensor ,
            dioName:loaderPlutoGatewayName,inputNumero:5,byteNumero:7) 

        loaderDefaultStatus ( DigitalSensor ,
            dioName:loaderPlutoGatewayName,inputNumero:6,byteNumero:7)

        loaderFilterGoodPositionStatus ( DigitalSensor ,
            dioName:loaderPlutoGatewayName,inputNumero:7,byteNumero:7)
        
        //key lock or permit signal
        keyLockSensors (ComplementarySensors,
            sensor:ref("keyLock"),
            sensorC:ref("keyLockb"),
        ) {
            keyLock (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:0, byteNumero:10)
            keyLockb (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:1, byteNumero:10)
        }
        
        //engineering key
        keyEngSensors (ComplementarySensors,
            sensor:ref("keyEng"),
            sensorC:ref("keyEngb"),
        ) {
            keyEng (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:2, byteNumero:10)
            keyEngb (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:3, byteNumero:10)
        }
        
        // output signals for Camera Protection System
        //LRH gateway 3, bits 4 & 5
        //LPS gateway 3, bits 6 & 7
        // LRH (Loader Holding Filter at HANDOFF)
        Loader_LRH (ComplementarySensors,
            sensor:ref("LRH_0"),
            sensorC:ref("LRH_1"),
        ) {
            LRH_0 (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:4, byteNumero:10)
            LRH_1 (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:5, byteNumero:10)
        }
        
        // LPS (Loader at STORAGE)
        Loader_LPS (ComplementarySensors,
            sensor:ref("LPS_0"),
            sensorC:ref("LPS_1"),
        ) {
            LPS_0 (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:6, byteNumero:10)
            LPS_1 (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:7, byteNumero:10)
        }
        
        //Signals comming from autochanger and read on loaderPlutoGateway//
        //AP2 user_to_gateway 3 input 0
        //AF0 user_to_gateway 3 input 1
        //AF1 user_to_gateway 3 input 2
        //AF3 user_to_gateway 3 input 3
        acAP2 (ComplementarySensors,
            sensor:ref("acAP2s"),
            sensorC:ref("acAP2b"),
        ) {
            acAP2s (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:0, byteNumero:11)
            acAP2b (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:1, byteNumero:11)
        }
        
        acAF0 (ComplementarySensors,
            sensor:ref("acAF0s"),
            sensorC:ref("acAF0b"),
        ) {
            acAF0s (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:2, byteNumero:11)
            acAF0b (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:3, byteNumero:11)
        } 
        
        acAF1 (ComplementarySensors,
            sensor:ref("acAF1s"),
            sensorC:ref("acAF1b"),
        ) {
            acAF1s (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:4, byteNumero:11)
            acAF1b (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:5, byteNumero:11)
        } 
        
        acAF3 (ComplementarySensors,
            sensor:ref("acAF3s"),
            sensorC:ref("acAF3b"),
        ) {
            acAF3s (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:6, byteNumero:11)
            acAF3b (DigitalSensor,
                dioName:loaderPlutoGatewayName, inputNumero:7, byteNumero:11)
        } 
        //end of Signals comming from autochanger and read on loaderPLutoGateway// 
            
    }//end description of loader's children
            
} // end description of main (FcsMain)
