package autochanger

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.common.EPOSControllerWithBrake
import org.lsst.ccs.subsystems.fcs.simulation.*
import org.lsst.ccs.subsystems.fcs.drivers.*
import org.lsst.ccs.drivers.canopenjni.*
import org.lsst.ccs.drivers.canopenjni.rmi.*
import org.lsst.ccs.monitor.Channel
import org.lsst.ccs.monitor.Device
import org.lsst.ccs.description.groovy.CCSBuilder

//************************************************************************//
// subsystem properties
// org.lsst.ccs.run.mode can be "simulation" or "hardware"
// org.lsst.ccs.fcs.instance.autochanger can be "PROTO", "AC1" or "AC2"
//************************************************************************//
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 subsystemName
//decide which subsystem to launch depending on runMode and instanceAC
if ("simulation".equals(runMode)) {
    subsystemName = "autochanger-standalone-simu"
} else if ("PROTO".equals(instanceAC)) {
    subsystemName = "autochanger-standalone_PROTO"
} else if ("AC2".equals(instanceAC)) {
    subsystemName = "autochanger-standalone_AC2"
} else {
    subsystemName = "autochanger-standalone_AC1"
} 

def acPlutoGatewayName = "acSensorsGateway" // to monitor the autochanger sensors

def truckXminusControllerName
def truckXplusControllerName

//************************************************************************//
//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.
//************************************************************************//
if ("AC1".equals(instanceAC) || "AC2".equals(instanceAC)) {
    truckXminusControllerName = "linearRailSlaveController";
    truckXplusControllerName = "linearRailMasterController";
} else {
    truckXminusControllerName = "linearRailMasterController";
    truckXplusControllerName = "linearRailSlaveController";
}

CCSBuilder builder = [subsystemName] 

builder.
    main (AutochangerMain, bridge:ref("tcpProxy"), carousel:ref("carousel"),loader:ref("loader"),
        nodeTags:["monitor-update/taskPeriodMillis":-1,"monitor-publish/taskPeriodMillis":-1, "monitor-check/taskPeriodMillis":-1]) {
    //begin description of Main submodules
    //-------------------------
    // 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
    // ------------------------------
    
    // tcp Proxy
    tcpProxy (CanOpenProxy, 
        canInterface:ref("canInterface")) 
    {
        
        //real hardware PROTO
        if ( "hardware".equals(runMode) && "PROTO".equals(instanceAC) ) {
            canInterface(CanOpenCommands, coi:new CanOpenRMIClient("134.158.154.195", "canbus0"));
            // can open devices
            //sensors gateway
            "$acPlutoGatewayName" (CanOpenPlutoGateway, nodeID:0x3a,serialNB:"3269")
            onlineStrainGauge (CanOpenStrainGauge, nodeID: 0x21, serialNB:"0")
            // can open motor controllers
            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",
            )
            
            //Devices which are the same classes for hardware and for simulation
            brakeSystemGateway (CanOpenPlutoGateway, nodeID:0x2b,serialNB:"2071")
            tempSensorsDevice (CanOpenSystecIO, nodeID: 0x20, serialNB:"4bb6b")
            proximitySensorsDevice (CanCBXAI420, nodeID: 0x22, serialNB:"c7c60331")
            
        //final produit AC1
        } else if ("hardware".equals(runMode) && "AC1".equals(instanceAC)) {
//            canInterface(CanOpenCommands, coi:new CanOpenRMIClient("134.158.155.193", "canbus0"));
//          to launch subsystem on the same CPU than canfestival
            canInterface(CanOpenCommands, coi:new CanFestivalJNI())
            // 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:"79026501",
            )
            // can open devices
            onlineClampXplusController (CanOpenEPOSOnlineClamp, 
                nodeID:0x30, serialNB:"79026465",
            )
            // can open devices
            onlineClampYminusController (CanOpenEPOSOnlineClamp, 
                nodeID:0x32, serialNB:"79026475",
            )
            
             //Devices which are the same classes for hardware and for simulation
            brakeSystemGateway (CanOpenPlutoGateway, nodeID:0x2b,serialNB:"4472")
            tempSensorsDevice1 (CanOpenSeneca4RTD, nodeID: 0x4a, serialNB:"19VE0077")
            tempSensorsDevice2 (CanOpenSeneca4RTD, nodeID: 0x4b, serialNB:"19VE0076")
            proximitySensorsDevice (CanCBXAI420, nodeID: 0x22, serialNB:"c7c60364")           
            
        //Simulation CAN open devices  
        } else {
            canInterface(SimuCanOpenInterface);
            "$acPlutoGatewayName" (SimuAutochangerStandalonePlutoGateway, nodeID:0x3a,serialNB:"3269")
            onlineStrainGauge (SimuCanOpenStrainGauge, nodeID: 0x21, serialNB:"0")
            // can open motor controllers
            linearRailMasterController (SimuAutochangerLinearRailController,    
                nodeID:0x2a,serialNB:"80001881",plutoGateway:ref("$acPlutoGatewayName"),
            )

            linearRailSlaveController (SimuAutochangerLinearRailController, 
                nodeID:0x2c,serialNB:"80001932",plutoGateway:ref("$acPlutoGatewayName"),
            )

            latchXminusController (SimuAutochangerLatchController,  //CanOpenEPOS24-3
                nodeID:0xf,serialNB:"84004735",latchName:"latchXminus",plutoGateway:ref("$acPlutoGatewayName"),
            )

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

            onlineClampXminusController (SimuAutochangerOnlineClampController, 
                nodeID:0x31,serialNB:"79011618",
                plutoGateway:ref("$acPlutoGatewayName"),
                onlineClampName:"onlineClampXminus",
            )

            onlineClampXplusController (SimuAutochangerOnlineClampController, 
                nodeID:0x30, serialNB:"79011616", 
                plutoGateway:ref("$acPlutoGatewayName"),
                onlineClampName:"onlineClampXplus",
            )
            
            onlineClampYminusController (SimuAutochangerOnlineClampController, 
                nodeID:0x32, serialNB:"79011243", 
                plutoGateway:ref("$acPlutoGatewayName"),
                onlineClampName:"onlineClampYminus",
            )
            
            //Devices which are the same classes for hardware and for simulation
            brakeSystemGateway (CanOpenPlutoGateway, nodeID:0x2b,serialNB:"2071")
            proximitySensorsDevice (CanCBXAI420, nodeID: 0x22, serialNB:"c7c60331") 
            tempSensorsDevice1 (CanOpenSeneca4RTD, nodeID: 0x4a, serialNB:"xxxxx")
            tempSensorsDevice2 (CanOpenSeneca4RTD, nodeID: 0x4b, serialNB:"yyyyyy")

            
        } //end of simulation CAN open devices description

        

    //************************************//            
    }//end description of bridge's children
    //************************************//
    //**************************************************************************//
    // end of Bridge
    //**************************************************************************//
    
    //-------------------------
    // 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

    // ------ 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:1, 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:2, 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:3, 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:4, 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
    carouselHoldingFilterSensors (ComplementarySensors,
            sensor:ref("carouselHoldingFilterSensor0"),
            sensorC:ref("carouselHoldingFilterSensor1")
        ){		
            carouselHoldingFilterSensor0(DigitalSensor ,		
                dioName:acPlutoGatewayName, inputNumero:6,byteNumero:3)		
            carouselHoldingFilterSensor1(DigitalSensor ,		
                dioName:acPlutoGatewayName, inputNumero:7,byteNumero:3)		
        }
    
    //holdingFilterSensor=1 ==> CFC = Filter locked in carousel socket
    
    //Loader_LRH
    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)    		
        }    

    //Loader_LPS
    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)		
    }

    //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 carouselStoppedAtStandbySensors children
    
    //Carousel_CF0    
    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 carousel_CF0 children 
    
    // Carousel_CF1    
    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 carousel_CF1 children  
    
    // Local Protection Module status to be read on autochanger plutoGateway
    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(Autochanger, plutoGateway:ref("$acPlutoGatewayName")) {
        
        //**************************************************************************//
        // 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
    //*****************************************************************************//
    //*****************************************************************************//

    /**********************************************************************/
    /*                FAKE CAROUSEL DESCRIPTION                       */
    /**********************************************************************/
    //in the autochanger standalone subsystem the fake carousel is a switch which
    //simulates that carousel holds a filter at STANDBY 
    carousel(FakeFilterHolder, holdingFilterSensorName:"carouselHoldingFilterSensors") // CFC
    /**********************************************************************/
    /*                END of FAKE CAROUSEL DESCRIPTION                 */
    /**********************************************************************/

    /**********************************************************************/
    /*                FAKE LOADER DESCRIPTION                       */
    /**********************************************************************/
    //in the autochanger standalone subsystem the fake loader is couple of complementary sensors
    //simulate that loader holds a filter at HANDOFF     
    loader(FakeFilterHolder, holdingFilterSensorName:"loaderHoldingFilterSensors")
    /**********************************************************************/
    /*                END of FAKE LOADER DESCRIPTION                 */
    /**********************************************************************/

}    // main
