Exemple #1
0
        /// <summary>
        /// writes the text to the specified file
        /// </summary>
        /// <param name="text">the text to write</param>
        /// <param name="path">the path of the file</param>
        /// <param name="append">if true, writes the text to the end of the file, otherwise overrides any existing file</param>
        /// <returns></returns>
        public async Task WriteTextToFileAsync(string text, string path, bool append = false)
        {
            // TODO: Add exception catching

            // normalize and resolve path
            path = NormalizePath(path);

            // resolve to absolute path
            path = ResolvePath(path);

            // is the path exits?
            if (!Directory.Exists(Path.GetDirectoryName(path)))
            {
                // generate a new folder in specified location
                Directory.CreateDirectory(Path.GetDirectoryName(path));
            }


            // lock the task
            await AsyncAwaiter.AwaitAsync(nameof(FileManager) + path, async() =>
            {
                // run the synchronous file access as new task
                await IoC.Task.Run(() =>
                {
                    // write the log message to a file
                    using (var fileStream = (TextWriter) new StreamWriter(File.Open(path, append ? FileMode.Append : FileMode.Create)))
                        fileStream.Write(text);
                });
            });
        }
Exemple #2
0
        /// <summary>
        /// Handles Omicron Hardware Configuration Settings
        /// </summary>
        /// <returns>Returns new Hardware Configuration</returns>
        public async Task HardwareConfiguration()
        {
            // is test running?
            if (!IoC.CMCControl.IsTestRunning)
            {
                // there is a test set attached so run specified tests.
                // lock the task
                await AsyncAwaiter.AwaitAsync(nameof(HardwareConfiguration), async() =>
                {
                    // set visibility of "Hardware Configuration" animation
                    IoC.Commands.IsConfigurationAvailable = true;

                    // find cmc
                    if (await IoC.Task.Run(() => IoC.FindCMC.Find()))
                    {
                        // let log start
                        await IoC.Task.Run(() => IoC.Logger.Log($"{nameof(HardwareConfiguration)} started."));

                        // update device info
                        await IoC.Task.Run(() => IoC.Logger.Log($"Following device associated: {IoC.CMCControl.DeviceInfo}."));

                        // save current page so we can return to it.
                        OldApplicationPage = IoC.Application.CurrentPage;
                        // save current view model so we can return to it.
                        OldViewModel = IoC.Application.CurrentPageViewModel;

                        // update log file about the connected Omicron capabilities.
                        await IoC.Task.Run(() => IoC.Logger.Log($"Following hardware configurations available:"));

                        // retrieve voltage capabilities if the list is empty.
                        IoC.Settings.OmicronVoltageOutputs = await IoC.Configurations.Get("voltage");
                        // retrieve current capabilities.
                        IoC.Settings.OmicronCurrentOutputs = await IoC.Configurations.Get("current");

                        // set visibility of command buttons
                        IoC.Commands.Cancellation           = true;
                        IoC.Commands.LoadTestAvailable      = false;
                        IoC.Commands.StartTestAvailable     = false;
                        IoC.Commands.NewTestAvailable       = IoC.TestDetails.SelectedCurrentConfiguration.CurrentWiringDiagram || IoC.TestDetails.SelectedVoltageConfiguration.CurrentWiringDiagram;
                        IoC.Commands.ConfigurationAvailable = false;

                        // change color of the Add New Test button to green.
                        IoC.Commands.CancelForegroundColor = "00ff00";


                        // Show Settings page
                        IoC.Application.GoToPage(ApplicationPage.Settings, IoC.Settings);

                        // disconnect from attached Omicron Test Set
                        await IoC.ReleaseOmicron.ReleaseAsync();
                    }
                });
            }
        }
Exemple #3
0
        /// <summary>
        /// Handles errors and stops the app gracefully.
        /// </summary>
        /// <param name="userRequest">true if test interrupt requested by the user
        /// false if test completed itself</param>
        public async Task ProcessErrorsAsync(bool userRequest = true)
        {
            await AsyncAwaiter.AwaitAsync(nameof(ProcessErrorsAsync), async() =>
            {
                try
                {
                    // update developer
                    IoC.Logger.Log($"Test {(userRequest ? "interrupted" : "completed")}", LogLevel.Informative);

                    // update the user
                    IoC.Communication.Log = $"{DateTime.Now.ToLocalTime():MM/dd/yy hh:mm:ss.fff}: Test { (userRequest ? "interrupted by the user." : "completed.")}";

                    // Turn off outputs of Omicron Test Set.
                    await IoC.Task.Run(async() => await IoC.PowerOptions.TurnOffCMCAsync());

                    // if the user wants to stop the test
                    if (userRequest)
                    {
                        // update In Progress test file
                        IoC.Communication.UpdateCurrentTestFileListItem(CommunicationViewModel.TestStatus.Interrupted);
                    }

                    // Disconnect Modbus Communication.
                    await IoC.Task.Run(() => IoC.Communication.EAModbusClient.Disconnect()).ConfigureAwait(continueOnCapturedContext: false);;

                    // check if timer is initialized then dispose it.
                    await IoC.Task.Run(() => IoC.CMCControl.MdbusTimer?.Dispose()).ConfigureAwait(continueOnCapturedContext: false);

                    // Progress bar is invisible
                    IoC.CMCControl.IsTestRunning = IoC.Commands.IsConnectionCompleted = IoC.Commands.IsConnecting = IoC.Communication.EAModbusClient.Connected;

                    // change color of Cancel Command button to Red
                    IoC.Commands.CancelForegroundColor = "ff0000";

                    // release omicron test set.
                    await IoC.Task.Run(async() => await ReleaseAsync());
                }
                catch (Exception)
                {
                    // re-throw error
                    throw;
                }
            });
        /// <summary>
        /// connects to omicron and test unit.
        /// </summary>
        private async Task ConnectOmicronAndUnitAsync()
        {
            // there is a test set attached so run specified tests.
            // lock the task
            await AsyncAwaiter.AwaitAsync(nameof(ConnectOmicronAndUnitAsync), async() =>
            {
                // decides which signal is our ramping signal by comparing the mismatch of any "From" and "To" values.
                // after the user clicked "Go" button
                TestSignal testSignal = new TestSignal();

                // is any signal ramping?
                if (testSignal.IsRamping)
                {
                    // is the user selected a hardware configuration?
                    if (testSignal.IsRunningPermitted)
                    {
                        // define the cancellation token source.
                        TokenSource = new CancellationTokenSource();

                        // define the cancellation token to use
                        // terminate tests prematurely.
                        Token = TokenSource.Token;

                        // Run test command
                        await IoC.Task.Run(() => IoC.TestDetails.ConnectCommand.Execute(IoC.TestDetails), Token);
                    }
                    else
                    {
                        // inform the user there is no hardware configuration available
                        IoC.Communication.Log = $"{DateTime.Now.ToLocalTime():MM/dd/yy HH:mm:ss.fff}: Running test is not permitted due to hardware configuration. Please check your configuration.";
                    }
                }
                else
                {
                    // inform the user there is no test case
                    IoC.Communication.Log = $"{DateTime.Now.ToLocalTime():MM/dd/yy HH:mm:ss.fff}: There is no ramping signal. Please check your entries.";
                }
            });
Exemple #5
0
        /// <summary>
        /// Turns on outputs of Omicron Test Set.
        /// </summary>
        public async Task TurnOnCMCAsync()
        {
            try
            {
                // lock the task
                await AsyncAwaiter.AwaitAsync(nameof(TurnOnCMCAsync), async() =>
                {
                    // update the developer
                    IoC.Logger.Log($"{nameof(TurnOnCMCAsync)} started.", LogLevel.Informative);

                    // Send command to Turn On Analog Outputs
                    await IoC.Task.Run(() => IoC.StringCommands.SendStringCommandsAsync(OmicronStringCmd.out_ana_on));

                    // update the developer
                    IoC.Logger.Log($"{nameof(TurnOnCMCAsync)} completed.", LogLevel.Informative);
                });
            }
            catch (Exception)
            {
                // re-throw error
                throw;
            }
        }
Exemple #6
0
        /// <summary>
        /// Allows to read test register values separated with comma specified by "Measurement Interval".
        /// </summary>
        public void MeasurementIntervalCallback(object Register)
        {
            // generate register(s) list
            List <string> registerStrings = new List <string>();

            // add Register to the list
            registerStrings.AddRange(Register.ToString().Split(','));

            // Use ParallelOptions instance to store the CancellationToken
            ParallelOptions parallelingOptions = new ParallelOptions
            {
                // associate cancellation token.
                CancellationToken = IoC.Commands.Token,
                // set limit for the parallelism equivalent of hardware core count
                MaxDegreeOfParallelism = Environment.ProcessorCount
            };

            // Partition the entire source array.
            var rangePartitioner = Partitioner.Create(0, registerStrings.Count);

            // inquire each register that specified by the user.
            Parallel.ForEach(rangePartitioner, parallelingOptions, async(registerString) =>
            {
                using (CancellationTokenSource cancellation = new CancellationTokenSource(new TimeSpan(0, 0, 0, Convert.ToInt32(IoC.TestDetails.MeasurementInterval))))
                {
                    // Listening to the cancellation event either the user or test completed.
                    var cancellationTask = Task.Run(() =>
                    {
                        if (IoC.Commands.Token.IsCancellationRequested)
                        {
                            // Sending the cancellation message
                            cancellation.Cancel();
                        }
                    });

                    try
                    {
                        // Loop over each range element without a delegate invocation.
                        for (int i = registerString.Item1; i < registerString.Item2; i++)
                        {
                            // start a task to read register address specified by the user.
                            await IoC.Task.Run(async() =>
                            {
                                // is the register is between modbus holding register range?
                                if (ushort.TryParse(registerStrings[i].Trim(), out ushort register))
                                {
                                    // lock the task
                                    await AsyncAwaiter.AwaitAsync(nameof(MeasurementIntervalCallback), async() =>
                                    {
                                        // start a task to read holding register (Function 0x03)
                                        int[] serverResponse = await IoC.Task.Run(() => ReadHoldingRegisterWithCancellationAsync(register: register, cancellationToken: cancellation.Token));

                                        // decide if serverResponse is acceptable only criteria is the length of the response.
                                        if (serverResponse.Length > 0)
                                        {
                                            // server response must be between 0 and 65535
                                            if (ushort.MinValue <= Math.Abs(serverResponse[0]) && ushort.MaxValue >= Math.Abs(serverResponse[0]))
                                            {
                                                // add new reading with the current time.
                                                IoC.CMCControl.RegisterReadingsWithTime[i].Add(DateTime.Now, serverResponse[0]);
                                            }
                                        }
                                        else
                                        {
                                            // server failed to respond. Ignoring it until find a better option.
                                            // inform the developer about error
                                            IoC.Logger.Log($"register: {register} -- serverResponse : No server response");
                                        }
                                    });
                                }
                                else
                                {
                                    // illegal register address
                                    throw new ArgumentOutOfRangeException($"Register: {registerStrings[i].Trim()} is out of range");
                                }
                            });
                        }
                    }
                    catch (Exception)
                    {
                        // re-throw error
                        throw;
                    }

                    // cancellation.Dispose();
                    await cancellationTask;
                }
            });
        }
        /// <summary>
        /// Starts a test with the values specified in Nominal Values page and
        /// Communication page.
        /// </summary>
        public async Task StartCommunicationAsync()
        {
            // start point of all test steps with the first mouse click and it will ignore subsequent mouse clicks
            await AsyncAwaiter.AwaitAsync(nameof(StartCommunicationAsync), async() =>
            {
                using (IoC.Commands.TokenSource)
                {
                    try
                    {
                        // update the user
                        Log = $"{DateTime.Now.ToLocalTime():MM/dd/yy HH:mm:ss.fff}: Communication starts.";

                        // get new construct of ModbusClient
                        EAModbusClient = new EasyModbus.ModbusClient
                        {
                            IPAddress         = IpAddress,
                            Port              = Convert.ToInt32(Port),
                            ConnectionTimeout = 20000,
                            // LogFileFilename = @"C:\Users\TBircek\Documents\metering\modbus.log"
                        };

                        // Checks if the Server IPAddress is available
                        if (EAModbusClient.Available(20000))
                        {
                            // connect to the server
                            EAModbusClient.Connect();

                            // find any CMCEngine attached to this computer
                            if (IoC.FindCMC.Find())
                            {
                                // Is there Omicron Test Set attached to this app?
                                if (IoC.CMCControl.DeviceID > 0)
                                {
                                    // indicates the test is running.
                                    IoC.CMCControl.IsTestRunning = true;

                                    try
                                    {
                                        // perform initial set up on CMCEngine
                                        await IoC.Task.Run(async() => await IoC.InitialCMCSetup.InitialSetupAsync());

                                        // there is a test set attached so run specified tests.
                                        await IoC.Task.Run(async() => await IoC.CMCControl.TestAsync(IoC.Commands.Token));
                                    }
                                    catch (OperationCanceledException ex)
                                    {
                                        // inform the developer about error
                                        IoC.Logger.Log($"Exception is : {ex.Message}");

                                        // update the user about the error.
                                        IoC.Communication.Log = $"{DateTime.Now.ToLocalTime():MM/dd/yy HH:mm:ss.fff}: Exception: {ex.Message}.";
                                    }
                                    catch (Exception ex)
                                    {
                                        // inform developer
                                        IoC.Logger.Log($"Exception: {ex.Message}");

                                        // update the user about failed test.
                                        IoC.Communication.Log = $"{DateTime.Now.ToLocalTime():MM/dd/yy HH:mm:ss.fff}: Test failed: {ex.Message}.";

                                        // catch inner exceptions if exists
                                        if (ex.InnerException != null)
                                        {
                                            // inform the user about more details about error.
                                            IoC.Communication.Log = $"{DateTime.Now.ToLocalTime():MM/dd/yy HH:mm:ss.fff}: Inner exception: {ex.InnerException}.";
                                        }
                                    }
                                    finally
                                    {
                                        // Trying to stop the app gracefully.
                                        await IoC.Task.Run(() => IoC.ReleaseOmicron.ProcessErrorsAsync(false));
                                    }
                                }
                                else
                                {
                                    // inform the user
                                    Log = $"{DateTime.Now.ToLocalTime():MM/dd/yy HH:mm:ss.fff}: Failed: Omicron Test Set ID is a zero.";
                                }
                            }
                            else
                            {
                                // inform the user
                                Log = $"{DateTime.Now.ToLocalTime():MM/dd/yy HH:mm:ss.fff}: Failed: There is no attached Omicron Test Set. Please attached a Omicron Test Set before test.";
                            }
                        }
                        else
                        {
                            // inform the user
                            Log = $"{DateTime.Now.ToLocalTime():MM/dd/yy HH:mm:ss.fff}: Failed: The server is not available: {EAModbusClient.IPAddress}.";
                        }
                    }
                    catch (Exception ex)
                    {
                        // inform the user about error.
                        Log = $"{DateTime.Now.ToLocalTime():MM/dd/yy HH:mm:ss.fff}: Start Communication failed: {ex.Message}.";

                        // catch inner exceptions if exists
                        if (ex.InnerException != null)
                        {
                            // inform the user about more details about error.
                            Log = $"{DateTime.Now.ToLocalTime():MM/dd/yy HH:mm:ss.fff}: Inner exception: {ex.InnerException}.";
                        }
                    }
                }
            });