Example #1
0
        /// <summary>
        /// Add a configuration to the dictionary.  This will create an AdcpSubsystemConfig based
        /// off the Subsystem and CEPO index given.  It will then add it to the dictionary.  It will
        /// then return the created AdcpSubsystemConfig.  If the AdcpSubsystemConfig could not be
        /// created, null will be returned.
        /// </summary>
        /// <param name="ss">Subsystem to add a configuration.</param>
        /// <param name="cepoIndex">CEPO index.</param>
        /// <returns>AdcpSubsystemConfig created with the given settings or null if one could not be created.</returns>
        private AdcpSubsystemConfig AddConfig(Subsystem ss, int cepoIndex)
        {
            AdcpSubsystemConfig asConfig = null;

            // If a bad Subsystem is given, we cannot use it
            if (!ss.IsEmpty())
            {
                // Determine how many of the given subsystem have been added to the dictionary
                // We need to generate SubsystemConfiguration index value.
                // SubsystemConfiguration index is based off the number of SubsystemConfigurations already
                // in the dictionary before this configuration is added.
                ushort ssCount = 0;
                foreach (AdcpSubsystemConfig configuration in SubsystemConfigDict.Values)
                {
                    // If the subsystems are the same, then increment the value
                    if (configuration.SubsystemConfig.SubSystem.Code == ss.Code)
                    {
                        ssCount++;
                    }
                }

                // Create all the subsystem configurations and add to the dictionary
                SubsystemConfiguration ssConfig = new SubsystemConfiguration(ss, (byte)cepoIndex, (byte)ssCount); // SubsystemConfiguration with the Index of the SubsystemConfiguration
                asConfig = new AdcpSubsystemConfig(ssConfig);                                                     // AdcpSubsystemConfig with the Subsystem, SubsystemConfig and CEPO index
                if (!SubsystemConfigDict.ContainsKey(asConfig.ToString()))
                {
                    SubsystemConfigDict.Add(asConfig.ToString(), asConfig);
                }
            }

            return(asConfig);
        }
Example #2
0
        /// <summary>
        /// Get the CEPO configuration character and index within the CEPO command.
        /// The configuration character is the Subsystem code for the configuration.  It
        /// represents the system type.  The Index represents where in teh CEPO command
        /// the configuration was located.  This determines the ping order of the configurations.
        /// It also make the configuration unique for a SubsystemConfiguration for a Subsystem.
        /// Get the Subsystem using the serial number and subsystem code.
        ///
        /// SubsystemConfiguaration CommandSetup: Index of the Configuration within Subsystem.  (Based off counting configurations for a subsystem)
        /// index: Location in CEPO for the Subsystem configuration.
        /// </summary>
        /// <param name="ssCode">Subsystem Code from the CEPO command.</param>
        /// <param name="cepoIndex">Location in the CEPO command of the Subsystem Code.</param>
        /// <param name="serial">Serial number for the ADCP.</param>
        /// <returns>Return the AdcpSubsystemConfig created or null if one could not be created.</returns>
        private AdcpSubsystemConfig AddConfig(byte ssCode, int cepoIndex, SerialNumber serial)
        {
            AdcpSubsystemConfig asConfig = null;

            // Get the Subsystem index from the serial number
            // If it cannot be found in the serial number, then it is
            // a bad Subsystem and we can not use the command.
            Subsystem ss = serial.GetSubsystem(ssCode);

            if (!ss.IsEmpty())
            {
                // Determine how many of the given subsystem have been added to the dictionary
                // We need to generate SubsystemConfiguration index value.
                // SubsystemConfiguration index is based off the number of SubsystemConfigurations already
                // in the dictionary before this configuration is added.
                ushort ssCount = 0;
                foreach (AdcpSubsystemConfig configuration in SubsystemConfigDict.Values)
                {
                    // If the subsystems are the same, then increment the value
                    if (configuration.SubsystemConfig.SubSystem.Code == ssCode)
                    {
                        ssCount++;
                    }
                }

                // Create all the subsystem configurations and add to the dictionary
                SubsystemConfiguration ssConfig = new SubsystemConfiguration(ss, (byte)cepoIndex, (byte)ssCount);   // SubsystemConfiguration with the CEPO index and Index of the SubsystemConfiguration
                asConfig = new AdcpSubsystemConfig(ssConfig);                                                       // AdcpSubsystemConfig with the Subsystem, SubsystemConfig and CEPO index
                SubsystemConfigDict.Add(asConfig.ToString(), asConfig);                                             // Add to the dictionary the configuration with the string as the key
            }

            return(asConfig);
        }
Example #3
0
        /// <summary>
        /// Add a given AdcpSubsystemConfig to the dictionary.  This will determine
        /// how many of the given subsystem type have already been added to the dictionary
        /// and generate a new index value.  It will then set the index value to the SubsysteConfiguration.
        /// It will then add the AdcpSubsystemConfig to the dictionary.
        /// </summary>
        /// <param name="asConfig">AdcpSubsystemConfig to add to the dictionary.</param>
        private void AddConfig(AdcpSubsystemConfig asConfig)
        {
            // Determine how many of the given subsystem have been added to the dictionary
            // We need to generate SubsystemConfiguration index value.
            // SubsystemConfiguration index is based off the number of SubsystemConfigurations already
            // in the dictionary before this configuration is added.
            ushort ssCount = 0;

            foreach (AdcpSubsystemConfig configuration in SubsystemConfigDict.Values)
            {
                // If the subsystems are the same, then increment the value
                if (configuration.SubsystemConfig.SubSystem.Code == asConfig.SubsystemConfig.SubSystem.Code)
                {
                    ssCount++;
                }
            }

            // Set the new Configuration index
            asConfig.SubsystemConfig.SubsystemConfigIndex = (byte)ssCount;

            // Set the new CEPO index
            // This is the last index for the CEPO command
            asConfig.SubsystemConfig.CepoIndex = Convert.ToByte(SubsystemConfigDict.Values.Count);

            // Add it to the dictionary
            SubsystemConfigDict.Add(asConfig.ToString(), asConfig);
        }
        /// <summary>
        /// Initialize the view model.
        /// </summary>
        /// <param name="config">AdcpSubsystemConfig for this view model.</param>
        /// <param name="configVM">Adcp Configuration view model.</param>
        public AdcpSubsystemConfigurationViewModel(AdcpSubsystemConfig config, AdcpConfigurationViewModel configVM)
            : base(string.Format("Subsystem Configuration {0}", config.ToString()))
        {
            ConfigKey = config.ToString();
            ConfigVM  = configVM;

            // Initialize values
            _events = IoC.Get <IEventAggregator>();
            _pm     = IoC.Get <PulseManager>();

            // Get the predictor from the selected project subsystem configuration
            // Create the VM
            //Predictor = config.Predictor as AdcpPredictor;
            //Predictor = _pm.SelectedProject.Configuration.SubsystemConfigDict[ConfigKey].Predictor as AdcpPredictor;
            CalcPrediction();
            RangeVM = new AdcpRangePlannerViewModel(PredictedProfileRange, PredictedBottomRange);

            // Update the properties with the latest values
            UpdateProperties();

            // Remove configuration command
            RemoveCommand = ReactiveCommand.Create();
            RemoveCommand.Subscribe(_ => OnRemoveCommand());

            // Edit the configuration command
            EditCommand = ReactiveCommand.Create();
            EditCommand.Subscribe(param => OnEditCommand(param));
        }
Example #5
0
        /// <summary>
        /// Add the configuration and then move to the next display.
        /// </summary>
        private void OnNextCommand()
        {
            if (_SelectedSubsystem != null)
            {
                AdcpSubsystemConfig ssConfig = null;
                _pm.SelectedProject.Configuration.AddConfiguration(_SelectedSubsystem, out ssConfig);
                _pm.SelectedProject.Save();

                _events.PublishOnUIThread(new ViewNavEvent(ViewNavEvent.ViewId.BroadbandModeView, ssConfig.ToString()));
            }
        }
Example #6
0
        /// <summary>
        /// Determine if the given object is equal to this
        /// object.  This will check the Subsystem, SubsystemConfiguration and Index
        /// are all the same.
        /// </summary>
        /// <param name="obj">Object to compare with this object.</param>
        /// <returns>TRUE = AdcpSubsystemConfig are the same.</returns>
        public override bool Equals(object obj)
        {
            //Check for null and compare run-time types.
            if (obj == null || GetType() != obj.GetType())
            {
                return(false);
            }

            AdcpSubsystemConfig p = (AdcpSubsystemConfig)obj;

            return(SubsystemConfig == p.SubsystemConfig);
        }
        /// <summary>
        /// Remove the subsystem configuration from the project and
        /// from the UI.
        /// </summary>
        private void OnRemoveCommand()
        {
            // Ensure a project is selected and if the key exist in the dictionary
            if (_pm.IsProjectSelected && _pm.SelectedProject.Configuration.SubsystemConfigDict.ContainsKey(ConfigKey))
            {
                AdcpSubsystemConfig ssConfig = _pm.SelectedProject.Configuration.SubsystemConfigDict[ConfigKey];

                _pm.SelectedProject.Configuration.RemoveAdcpSubsystemConfig(ssConfig);

                ConfigVM.RemoveConfiguration(this);
            }
        }
Example #8
0
        /// <summary>
        /// Add a configuration.  This will take a Subsystem as a parameter.
        /// It will then create a new configuration for the given Subsystem.
        /// It will update the CEPO command and it will add the new Configuration
        /// to the dictionary.
        /// This will add a specific configuration but only update the CEPO command
        /// if the
        /// </summary>
        /// <param name="ss">Subsystem for the configuration.</param>
        /// <param name="asConfig">Return the AdcpSubsystemConfig created.</param>
        /// <param name="cepoIndex">The CEPO Index to use.</param>
        /// <returns>TRUE = Configuration Added. / FALSE = Configuration could not be added.</returns>
        public bool AddConfiguration(Subsystem ss, out AdcpSubsystemConfig asConfig, int cepoIndex)
        {
            // Initialize the AdcpSubsystemConfig to null
            asConfig = null;

            // Generate a new CEPO
            //string cepo = CEPO + Convert.ToChar(ss.Code);
            //string cepo = Commands.CEPO + Convert.ToChar(ss.Code);
            string cepo = AddConfigToCepo(ss.Code, cepoIndex);

            // Validate the new CEPO
            // If it pass, then add the new configuration to the dictionary
            if (ValidateCEPO(cepo, SerialNumber))
            {
                // Set the CEPO
                //CEPO = cepo;
                Commands.CEPO = cepo;

                // Get the CEPO index
                // The index will be the last character in the CEPO command
                // Subtract 1 because it is 0 based
                //int cepoIndex = Commands.CEPO.Length - 1;

                // Add the configuration to the dictionary
                // Set the AdcpSubsystemConfig to give to the user
                asConfig = AddConfig(ss, cepoIndex);

                return(true);
            }

            // If the data is DVL data, add the config
            if (SerialNumber == SerialNumber.DVL)
            {
                // Set the CEPO
                //CEPO = cepo;
                Commands.CEPO = cepo;

                // Get the CEPO index
                // The index will be the last character in the CEPO command
                // Subtract 1 because it is 0 based
                //int cepoIndex = Commands.CEPO.Length - 1;

                // Add the configuration to the dictionary
                // Set the AdcpSubsystemConfig to give to the user
                asConfig = AddConfig(ss, cepoIndex);

                return(true);
            }

            return(false);
        }
Example #9
0
        /// <summary>
        /// Update the serial number of the serial number generater updates the number.
        /// </summary>
        private void SerialNumberGeneratorVM_UpdateEvent()
        {
            AdcpSerialNumber = SerialNumberGeneratorVM.SerialNumber.ToString();
            _pm.SelectedProject.SerialNumber = SerialNumberGeneratorVM.SerialNumber;
            AdcpSerialNumber += "\n";
            AdcpSerialNumber += _pm.SelectedProject.SerialNumber.GetSerialNumberDescString(true);

            // Add a default configuration for the new subsystem added
            if (SerialNumberGeneratorVM.SerialNumber.SubSystemsList.Count > 0)
            {
                AdcpSubsystemConfig config = null;
                _pm.SelectedProject.Configuration.AddConfiguration(SerialNumberGeneratorVM.SerialNumber.SubSystemsList.Last(), out config);
            }
        }
Example #10
0
        public void TestConstructor()
        {
            Subsystem ss = new Subsystem(Subsystem.SUB_1_2MHZ_4BEAM_20DEG_PISTON_2, 0);         // 1200kHz
            SubsystemConfiguration ssConfig = new SubsystemConfiguration(ss, 0, 0);             // 0 Config
            int cepoIndex = 0;
            AdcpSubsystemConfig asConfig = new AdcpSubsystemConfig(ssConfig);
            string asConfigStr           = AdcpSubsystemConfig.GetString(ssConfig);


            Assert.AreEqual(asConfig.SubsystemConfig.CepoIndex, cepoIndex, "CepoIndex is incorrect.");
            //Assert.AreEqual(asConfig.Commands.CepoIndex, cepoIndex, "Commands CEPO index is incorrect.");
            Assert.AreEqual(asConfig.SubsystemConfig.SubSystem, ss, "Subsystem is incorrect.");
            Assert.AreEqual(asConfig.SubsystemConfig, ssConfig, "SubsystemConfiguration is incorrect.");
            Assert.AreEqual(asConfig.ToString(), "[0] 1.2 MHz 4 beam 20 degree piston", "ToString is incorrect.");
            Assert.AreEqual(asConfigStr, "[0] 1.2 MHz 4 beam 20 degree piston", "GetString is incorrect.");
        }
        /// <summary>
        /// Initialize the view model.
        /// </summary>
        /// <param name="config">Subsystem configuration.</param>
        /// <param name="dvlSetupVM">DVL Setup VM.</param>
        public DvlSubsystemConfigurationViewModel(ref AdcpSubsystemConfig config, DvlSetupViewModel dvlSetupVM)
            : base("DVL Subsystem Configuration")
        {
            // Initialize values
            _dvlSetupVM   = dvlSetupVM;
            AdcpSubConfig = config;
            if (config != null)
            {
                Desc = config.ToString();
            }

            Init();

            // Add Subsystem
            RemoveSubsystemCommand = ReactiveCommand.Create();
            RemoveSubsystemCommand.Subscribe(_ => RemoveSubsystem());
        }
Example #12
0
        public void TestJSON1()
        {
            Subsystem ss = new Subsystem(Subsystem.SUB_1_2MHZ_VERT_PISTON_A, 0);                // 1200kHz
            SubsystemConfiguration ssConfig = new SubsystemConfiguration(ss, 3, 3);             // 3 Config
            int cepoIndex = 3;
            AdcpSubsystemConfig asConfig = new AdcpSubsystemConfig(ssConfig);

            string json = Newtonsoft.Json.JsonConvert.SerializeObject(asConfig);                                        // Serialize object to JSON
            AdcpSubsystemConfig newConfig = Newtonsoft.Json.JsonConvert.DeserializeObject <AdcpSubsystemConfig>(json);  // Deserialize the JSON

            Assert.AreEqual(asConfig.SubsystemConfig.CepoIndex, cepoIndex, "CepoIndex is incorrect.");
            Assert.AreEqual(asConfig.SubsystemConfig.SubSystem, ss, "Subsystem is incorrect.");
            Assert.AreEqual(asConfig.SubsystemConfig, ssConfig, "SubsystemConfiguration is incorrect.");
            Assert.AreEqual(asConfig.ToString(), "[3] 1.2 MHz vertical beam piston", "ToString is incorrect.");

            Assert.AreEqual(newConfig.SubsystemConfig.CepoIndex, cepoIndex, "CepoIndex is incorrect.");
            Assert.AreEqual(newConfig.SubsystemConfig.SubSystem, ss, "Subsystem is incorrect.");
            Assert.AreEqual(newConfig.SubsystemConfig, ssConfig, "SubsystemConfiguration is incorrect.");
            Assert.AreEqual(newConfig.ToString(), "[3] 1.2 MHz vertical beam piston", "ToString is incorrect.");
        }
Example #13
0
        /// <summary>
        /// Get the AdcpSubsystemConfig from the dictionary if it exist.  If it does not
        /// exist in the dictionary, null will be returned.
        /// </summary>
        /// <param name="ssConfig">SubsystemConfiguration.</param>
        /// <returns>If the AdcpSubystemConfig is found, it will return the AdcpSubsystemConfig.  If it is not found, it will return null.</returns>
        public AdcpSubsystemConfig GetAdcpSubsystemConfig(SubsystemConfiguration ssConfig)
        {
            // Check for null
            if (ssConfig == null)
            {
                return(null);
            }

            // Generate the key for the Subsystem and SubsystemConfiguration
            string key = AdcpSubsystemConfig.GetString(ssConfig);

            // If the key exist, return the object
            if (SubsystemConfigDict.ContainsKey(key))
            {
                return(SubsystemConfigDict[key]);
            }

            // The key did not exist so return null
            return(null);
        }
Example #14
0
        /// <summary>
        /// Remove the AdcpSubsystemConfig from the dictionary.  If it exist in the
        /// dictionary, the AdcpSubsystemConfigs in the dictionary have to reordered.
        /// If it did not exist in the dictionary, do nothing and return false.
        ///
        /// Create a temporary list of all the configurations in the order
        /// of the CEPO command.  Then add the configurations back to the dictonary
        /// and create a new CEPO command.
        /// </summary>
        /// <param name="config">AdcpSubsystemConfig to remove.</param>
        /// <returns>TRUE = Config removed / FALSE = Config did not exist in the dictonary.  Nothing done.</returns>
        public bool RemoveAdcpSubsystemConfig(AdcpSubsystemConfig config)
        {
            if (config != null)
            {
                // Remove the AdcpSubsystemConfig from the dict
                // If it is removed, all the remaining configurations needed
                // to be renumbered
                if (SubsystemConfigDict.Remove(config.ToString()))
                {
                    // Remove all the configurations from the dictionary and put in an sorted list by CEPO index
                    SortedList <int, AdcpSubsystemConfig> tempList = new SortedList <int, AdcpSubsystemConfig>();
                    //List<AdcpSubsystemConfig> tempList = new List<AdcpSubsystemConfig>();
                    foreach (AdcpSubsystemConfig asConfig in SubsystemConfigDict.Values)
                    {
                        tempList.Add(asConfig.SubsystemConfig.CepoIndex, asConfig);
                        //tempList.Add(asConfig);
                    }

                    // Clear the dictionary and the CEPO command
                    //CEPO = "";
                    Commands.CEPO = AdcpCommands.DEFAULT_CEPO;
                    SubsystemConfigDict.Clear();

                    // Redo the CEPO command
                    // and add the configuration back to the dictionary
                    for (int x = 0; x < tempList.Count; x++)
                    {
                        // Redo the cepo value
                        Commands.CEPO += Convert.ToChar(tempList.Values[x].SubsystemConfig.SubSystem.Code);

                        // Add config to the dictionary
                        AddConfig(tempList.Values[x]);
                    }

                    return(true);
                }
            }

            // Config was not in the list so the configuration was not reordered
            return(false);
        }
Example #15
0
        public void TestJSON()
        {
            Subsystem ss = new Subsystem(Subsystem.SUB_1_2MHZ_4BEAM_20DEG_PISTON_2, 0);         // 1200kHz
            SubsystemConfiguration ssConfig = new SubsystemConfiguration(ss, 0, 0);             // 0 Config
            int cepoIndex = 0;
            AdcpSubsystemConfig asConfig = new AdcpSubsystemConfig(ssConfig);

            string json = Newtonsoft.Json.JsonConvert.SerializeObject(asConfig);                                        // Serialize object to JSON
            AdcpSubsystemConfig newConfig = Newtonsoft.Json.JsonConvert.DeserializeObject <AdcpSubsystemConfig>(json);  // Deserialize the JSON

            Assert.AreEqual(asConfig.SubsystemConfig.CepoIndex, cepoIndex, "CepoIndex is incorrect.");
            //Assert.AreEqual(asConfig.Commands.CepoIndex, cepoIndex, "Commands CEPO index is incorrect.");
            Assert.AreEqual(asConfig.SubsystemConfig.SubSystem, ss, "Subsystem is incorrect.");
            Assert.AreEqual(asConfig.SubsystemConfig, ssConfig, "SubsystemConfiguration is incorrect.");
            Assert.AreEqual(asConfig.ToString(), "[0] 1.2 MHz 4 beam 20 degree piston", "ToString is incorrect.");

            Assert.AreEqual(newConfig.SubsystemConfig.CepoIndex, cepoIndex, "CepoIndex is incorrect.");
            //Assert.AreEqual(newConfig.Commands.CepoIndex, cepoIndex, "Commands CEPO index is incorrect.");
            Assert.AreEqual(newConfig.SubsystemConfig.SubSystem, ss, "Subsystem is incorrect.");
            Assert.AreEqual(newConfig.SubsystemConfig, ssConfig, "SubsystemConfiguration is incorrect.");
            Assert.AreEqual(newConfig.ToString(), "[0] 1.2 MHz 4 beam 20 degree piston", "ToString is incorrect.");
        }
Example #16
0
        /// <summary>
        /// Add a configuration to the canvas.  Give the subsystem configuration and
        /// add it to the list of configurations.  This will add the ping time and the
        /// CEI timing.
        /// </summary>
        /// <param name="ssConfig">Subsystem configuration.</param>
        /// <param name="numConfigs">Number of configurations.</param>
        /// <param name="CEI">CEI time in seconds.</param>
        /// <param name="pixelsPerSecond">Number of pixels per second.</param>
        /// <param name="startPixel">Start pixel.</param>
        /// <returns>Total time included CEI.</returns>
        private double AddConfigCanvas(AdcpSubsystemConfig ssConfig, int numConfigs, double CEI, double pixelsPerSecond, double startPixel)
        {
            // Configuration number to know  the location to put the model
            // and to label the model
            int configNum = ssConfig.SubsystemConfig.CepoIndex;

            // Get the CWPP and CWPTBP time
            double cwppTime = ssConfig.Commands.CWPTBP * ssConfig.Commands.CWPP;

            // Time to ping
            // Calculate the time for a single ping based off the depth profiling and the 1.5ms per meter
            //double pingTime = 0.1;
            double pingTime = (1.5 / 1000) * (ssConfig.Commands.CWPBL + (ssConfig.Commands.CWPBS * ssConfig.Commands.CWPBN));  // 1.5ms per meter

            // Check if the CWPP and CWPTBP exceeds the CEI time
            if (ssConfig.Commands.CWPP > 1)
            {
                pingTime = cwppTime;           // If more than one ping is in the ensemble
            }
            double ensembleLength = (pingTime * pixelsPerSecond);

            // CEI length or CBI Length
            double ceiLength = (CEI * pixelsPerSecond) - ensembleLength;

            if (ceiLength < 0)
            {
                ceiLength = 0;
            }

            // Calculate the ping time
            double ceiTimeLeft = CEI - pingTime;

            if (ceiTimeLeft < 0)
            {
                ceiTimeLeft = 0;                                                    // Set 0 as the smallest
            }

            // If Burst Mode is used, replace the values
            if (ssConfig.Commands.CBI_BurstInterval.ToSecondsD() > 0)
            {
                // Burst Pinging
                pingTime       = ssConfig.Commands.CBI_NumEnsembles * CEI;
                ensembleLength = (pingTime * pixelsPerSecond);

                // Burst Length
                ceiLength = (ssConfig.Commands.CBI_BurstInterval.ToSecondsD() * pixelsPerSecond) - ensembleLength;

                // Time Remaining
                ceiTimeLeft = ssConfig.Commands.CBI_BurstInterval.ToSecondsD() - pingTime;
            }

            // Width
            // Based off the number of configurations
            double startWidth = startPixel;

            // Height
            // Start at top and go down half way
            double startHeight = (PingModelCanvas.Height / numConfigs) * configNum;;
            double endHeight   = (PingModelCanvas.Height / numConfigs);

            // Ensemble
            double widthEnsStart  = startWidth;
            double heightEnsStart = startHeight;
            double widthEnsEnd    = widthEnsStart + ensembleLength;
            double heightEnsEnd   = endHeight;

            // CEI
            double widthCeiStart  = widthEnsEnd;
            double heightCeiStart = startHeight;
            double widthCeiEnd    = widthCeiStart + ceiLength;
            double heightCeiEnd   = endHeight;


            // Gradient
            LinearGradientBrush linGrBrush = new LinearGradientBrush(Color.FromArgb(255, 29, 29, 29),
                                                                     Color.FromArgb(255, 14, 14, 14),
                                                                     90);

            // Add Ensemble
            System.Windows.Shapes.Rectangle rectEns;
            rectEns                 = new System.Windows.Shapes.Rectangle();           // Create a rectangle
            rectEns.Stroke          = new SolidColorBrush(Colors.Black);               // Border color
            rectEns.StrokeThickness = 10;
            rectEns.Fill            = linGrBrush;
            rectEns.Width           = ensembleLength;                                  // Ensemble Length
            rectEns.Height          = endHeight;                                       // Ensemble Height
            Canvas.SetLeft(rectEns, widthEnsStart);                                    // Location of the rectangle Width
            Canvas.SetTop(rectEns, heightEnsStart);                                    // Location of the rectangle Height
            PingTimingCanvas.Children.Add(rectEns);                                    // Add the rectangle to the canvas

            // Add CEI
            System.Windows.Shapes.Rectangle rectCEI;
            rectCEI                 = new System.Windows.Shapes.Rectangle();       // Create a rectangle
            rectCEI.Stroke          = new SolidColorBrush(Colors.Gray);            // Border color
            rectCEI.StrokeThickness = 10;                                          // Thicker border
            rectCEI.Fill            = new SolidColorBrush(Colors.Transparent);     // No fill color
            rectCEI.Width           = ceiLength;                                   // CEI Length
            rectCEI.Height          = endHeight;                                   // CEI height
            Canvas.SetLeft(rectCEI, widthCeiStart);                                // Location of the rectangle Width
            Canvas.SetTop(rectCEI, heightCeiStart);                                // Location of the rectangle Height
            PingTimingCanvas.Children.Add(rectCEI);                                // Add the rectangle to the canvas

            // Add the Ensemble Length labels
            TextBlock textBlockEns = new TextBlock();

            if (ssConfig.Commands.CBI_BurstInterval.ToSecondsD() <= 0 && pingTime > CEI)
            {
                textBlockEns.Foreground = Brushes.Red;                              // Give a warning that the ping time exceeds CEI
            }
            textBlockEns.Text     = "[" + ssConfig.SubsystemConfig.CepoIndex + "] " + pingTime.ToString("0.000") + " sec";
            textBlockEns.FontSize = 40;                                             // Font size
            Canvas.SetLeft(textBlockEns, widthEnsStart + (ensembleLength / 2));     // Put in the middle of the box Width
            Canvas.SetTop(textBlockEns, heightEnsStart + (endHeight));              // Put in the middle of the box Height
            PingTimingCanvas.Children.Add(textBlockEns);                            // Add the text to the canvas

            // Add the CEI Length labels
            TextBlock textBlockCei = new TextBlock();

            textBlockCei.Text     = ceiTimeLeft.ToString("0.000") + " sec";
            textBlockCei.FontSize = 40;                                             // Font size
            Canvas.SetLeft(textBlockCei, widthCeiStart + (ceiLength / 2));          // Put in the middle of the box Width
            Canvas.SetTop(textBlockCei, heightCeiStart + (endHeight));              // Put in the middle of the box Height
            PingTimingCanvas.Children.Add(textBlockCei);                            // Add the text to the canvas

            // If burst mode, return the burst length
            if (ssConfig.Commands.CBI_BurstInterval.ToSecondsD() > 0)
            {
                return(ssConfig.Commands.CBI_BurstInterval.ToSecondsD());
            }

            // IF the CWPP and CWPTBP exceeds CEI
            // Then return the larger time
            if (cwppTime > CEI)
            {
                return(cwppTime);
            }

            // Return CEI
            return(CEI);
        }