void fire_results_status(CalibrationResultsEventArgs e)
 {
     if (CalibrationResults_Event != null)
     {
         CalibrationResults_Event(this, e);
     }
 }
        /// <summary>
        /// Handle the calibration results
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void calibration_Results_Event(object sender, CalibrationResultsEventArgs e)
        {
            // Check whether db logging is disabled
            if (!isDBLogingEnabled())
                return;

            DataRow r = _datatable_calibrate.NewRow();
            r["VoltageGain"] = e.Voltage_gain;
            r["CurrentGain"] = e.Current_gain;
            r["Eui"] = e.EUI;
            r["DateCalibrated"] = e.Timestamp;

            lock (_datatable_calibrate)
            {
                _datatable_calibrate.Rows.Add(r);
            }

            if (_task_updatedb == null || _task_updatedb.Status != TaskStatus.Created)
            {
                _task_updatedb = new Task(updateDB);
            }

            if (_task_updatedb.Status != TaskStatus.Running)
            {
                _task_updatedb.Start();
            }

            if (_datatable_calibrate.Rows.Count > 10000)
            {
                _datatable_calibrate.Rows.Clear();
            }
        }
        /// <summary>
        /// Calibrates using just the Ember
        /// Voltage and Current register values are gathered using custom commands
        /// </summary>
        public void Run(CancellationToken cancel)
        {
            string datain, msg;

            datain = _telnet_connection.Read();
            TraceLogger.Log(datain);

            // Patch gain to 1
            fire_run_status("Patch Gain to 1");
            msg = patch(0x400000, 0x400000);
            TraceLogger.Log(msg);

            // Note there is a problem with Hornshark/Mudshark not resetting after a patch
            reset_workaround();

            Thread.Sleep(1000);
            datain = _telnet_connection.Read();
            TraceLogger.Log(datain);

            // Connect the load and verify ac
            _relay_ctrl.WriteLine(Relay_Lines.Load, true);

            Thread.Sleep(1000);
            verify_voltage_ac();

            string cmd_prefix = TCLI.Get_Custom_Command_Prefix(_telnet_connection);
            TraceLogger.Log("cmd_prefix = " + cmd_prefix);

            string eui = TCLI.Get_EUI(_telnet_connection);
            TraceLogger.Log("eui = " + eui);

            // Get UUT current/voltage values
            fire_run_status("Get UUT values");

            TCLI.Current_Voltage cv = new TCLI.Current_Voltage();
            double power1 = 0.0, power2 = 0.0;
            int max_try_count = 5;
            for (int i = 0; i < max_try_count; i++)
            {
                // Close the UUT relay
                // Jigs short-out the relay....
                if (_board_type == BoardTypes.Humpback)
                {
                    // With Shuko we could not short relay
                    TraceLogger.Log("Set_Relay_State ON");
                    TCLI.Set_Relay_State(_telnet_connection, true);
                }

                bool error_reading = false;
                try
                {
                    cv = TCLI.Parse_Pload_Registers(
                        _telnet_connection, cmd_prefix, _voltage_ac_reference, _current_ac_reference);
                }
                catch (Exception ex)
                {
                    if (i + 1 >= max_try_count)
                    {
                        throw;
                    }
                    error_reading = true;
                    fire_status(ex.Message + ".  Retrying...");
                }

                if (!error_reading)
                {
                    power1 = cv.Voltage * cv.Current;
                    double delta1 = 100;
                    if (power1 != 0)
                        delta1 = Math.Abs((power2 - power1) * 100 / power1);

                    msg = string.Format("Cirrus I = {0:F8}, V = {1:F8}, P = {2:F8}, D = {3:F8}",
                        cv.Current, cv.Voltage, cv.Current * cv.Voltage, delta1);
                    fire_status(msg);
                    //TraceLogger.Log(msg);

                    if (delta1 != 100.0 && delta1 != 0.0 && delta1 < 1.0)
                        break;
                }
                power2 = power1;
                Thread.Sleep(250);
            }

            if (cv.Voltage < _uut_voltage_ac_low_limit || cv.Voltage > _uut_voltage_ac_high_limit)
            {
                msg = string.Format(
                    "Cirrus voltage before calibration not within allowed limit values: {0:F8} < {1:F8} < {2:F8}",
                    _uut_voltage_ac_low_limit, cv.Voltage, _uut_voltage_ac_high_limit);
                throw new Exception(msg);
            }
            if (cv.Current < _uut_current_ac_low_limit || cv.Current > _uut_current_ac_high_limit)
            {
                msg = string.Format(
                    "Cirrus current before calibration not within allowed limit values: {0:F8} < {1:F8} < {2:F8}",
                    _uut_current_ac_low_limit, cv.Current, _uut_current_ac_high_limit);
                throw new Exception(msg);
            }

            /// The meter measurements
            fire_run_status("Meter measurements");
            double current_meter;
            if (_meter == null)
            {
                Form_EnterMeasurement dlg = new Form_EnterMeasurement();
                current_meter = dlg.GetMeasurement("Enter AC Current");
            }
            else
            {
                _meter.Init();
                _meter.SetupForIAC();
                string current_meter_str = _meter.Measure();
                current_meter_str = _meter.Measure();

                try
                {
                    current_meter = Double.Parse(current_meter_str);
                }
                catch (Exception)
                {
                    throw;
                }

                // Note that input should be on white 0.5 A terminal
                // Make sure System->Language = COMP
                if (_meter.Model == MultiMeter.Models.GDM8341)
                    current_meter /= 1000;
            }
            msg = string.Format("Meter I = {0:F8}", current_meter);
            TraceLogger.Log(msg);

            double voltage_meter;
            if (_meter == null)
            {
                Form_EnterMeasurement dlg = new Form_EnterMeasurement();
                voltage_meter = dlg.GetMeasurement("Enter AC Voltage");
            }
            else
            {
                _meter.SetupForVAC();
                string voltage_meter_str = _meter.Measure();
                voltage_meter_str = _meter.Measure();
                _meter.CloseSerialPort();
                voltage_meter = Double.Parse(voltage_meter_str);
            }
            msg = string.Format("Meter I = {0:F8}, V = {1:F8}, P = {2:F8}",
                current_meter, voltage_meter, current_meter * voltage_meter);
            fire_status(msg);

            //if (voltage_meter < 100 || voltage_meter > 260)
            if (voltage_meter < _load_voltage_ac_low_limit || voltage_meter > _load_voltage_ac_high_limit)
            {
                msg = string.Format(
                    "Meter voltage before calibration not within limit values: {0:F8} < {1:F8} < {2:F8}",
                    _load_voltage_ac_low_limit, voltage_meter, _load_voltage_ac_high_limit);
                throw new Exception(msg);
            }

            if (current_meter < _load_current_ac_low_limit || current_meter > _load_current_ac_high_limit)
            //if (current_meter < 0.01 || current_meter > 1)
            {
                msg = string.Format(
                    "Meter current before calibration not within limit values: {0:F8} < {1:F8} < {2:F8}",
                    _load_current_ac_low_limit, current_meter, _load_current_ac_high_limit);
                //msg = string.Format("Meter current before calibration not within limit values: {0:F8} < {1:F8} < {2:F8}", 0.01, current_meter, 1);
                throw new Exception(msg);
            }

            // Gain calculations
            fire_run_status("Gain calculations");
            double current_gain = current_meter / cv.Current;
            //double current_gain = current_meter / current_cs;
            int current_gain_int = (int)(current_gain * 0x400000);
            msg = string.Format("Current Gain = {0:F8} (0x{1:X})", current_gain, current_gain_int);
            fire_status(msg);

            double voltage_gain = voltage_meter / cv.Voltage;
            int voltage_gain_int = (int)(voltage_gain * 0x400000);
            msg = string.Format("Voltage Gain = {0:F8} (0x{1:X})", voltage_gain, voltage_gain_int);
            fire_status(msg);

            CalibrationResultsEventArgs args_results = new CalibrationResultsEventArgs();
            args_results.Timestamp = DateTime.Now;
            args_results.EUI = eui;
            args_results.Voltage_gain = voltage_gain_int;
            args_results.Current_gain = current_gain_int;
            fire_results_status(args_results);

            // Patch new gain
            fire_run_status("Patch Gain");
            msg = patch(voltage_gain_int, current_gain_int);
            TraceLogger.Log(msg);

            // Note there is a problem with Hornshark/Mudshark not resetting after a patch
            reset_workaround();

            Thread.Sleep(3000);
            datain = _telnet_connection.Read();
            TraceLogger.Log(datain);

            _telnet_connection.WriteLine(string.Format("cu {0}_pinfo", cmd_prefix));
            Thread.Sleep(500);
            datain = _telnet_connection.Read();
            TraceLogger.Log(datain);

            // Get UUT current/voltage values
            fire_run_status("Get UUT calibrated values");
            power1 = 0.0; power2 = 0.0;
            cv = new TCLI.Current_Voltage();
            max_try_count = 5;
            for (int i = 0; i < max_try_count; i++)
            {
                bool error_reading = false;
                try
                {
                    cv = TCLI.Parse_Pload_Registers(
                        _telnet_connection, cmd_prefix, _voltage_ac_reference, _current_ac_reference);
                }
                catch (Exception ex)
                {
                    if (i + 1 >= max_try_count)
                    {
                        throw;
                    }
                    error_reading = true;
                    fire_status(ex.Message + ".  Retrying...");
                }

                if (!error_reading)
                {
                    power1 = cv.Voltage * cv.Current;
                    double delta1 = 100;
                    if (power1 != 0)
                        delta1 = Math.Abs((power2 - power1) * 100 / power1);

                    msg = string.Format("Cirrus I = {0:F8}, V = {1:F8}, P = {2:F8}, D = {3:F8}",
                        cv.Current, cv.Voltage, cv.Current * cv.Voltage, delta1);
                    fire_status(msg);

                    if (delta1 != 100.0 && delta1 != 0.0 && delta1 < 1.0)
                        break;
                }
                power2 = power1;
                Thread.Sleep(250);
            }

            // Check calibration
            double delta = voltage_meter * 0.3;
            double high_limit = voltage_meter + delta;
            double low_limit = voltage_meter - delta;
            if (cv.Voltage < low_limit || cv.Voltage > high_limit)
            {
                msg = string.Format(
                    "Voltage after calibration not within limit values: {0:F8} < {1:F8} < {2:F8}",
                    low_limit, cv.Voltage, high_limit);
                TraceLogger.Log(msg);
                throw new Exception(msg);
            }
            delta = current_meter * 0.3;
            high_limit = current_meter + delta;
            low_limit = current_meter - delta;
            if (cv.Current < low_limit || cv.Current > high_limit)
            {
                msg = string.Format(
                    "Current after calibration not within limit values: {0:F8} < {1:F8} < {2:F8}",
                    low_limit, cv.Current, high_limit);
                TraceLogger.Log(msg);
                throw new Exception(msg);
            }
        }