tbf/GenericTest/GenericTestDlg.cs

1043 lines
46 KiB
C#

///
/// Copyright (c) 2019-2022 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using log4net;
using Common;
using SharedDatabase;
using SharedDatabase.Entities;
using SharedDatabase.Forms;
using TBF.Rig.Modbus.Common;
using NHibernate;
using Oracle.DataAccess.Client; // ODP.NET Oracle managed provider
using RecordProcessing;
using GenericTest.Resources;
namespace GenericTest
{
public partial class GenericTestDlg : Form
{
static readonly ILog log = LogManager.GetLogger(typeof(GenericTestDlg));
static readonly ILog results = LogManager.GetLogger("Results");
static readonly ILog badResults = LogManager.GetLogger("BadResults");
const int ErrorBeepFrequency = 500; /// Hz
const int ErrorBeepDuration = 1000; /// ms
#if RF_TEST
public RecordProcessing.RecordType RcrdType = RecordType.RF_Test;
public const string WorkflowStep = "rf_power";
public const string DfltWorkplaceName = "RF Test";
#elif RF_TEST_400_900
public RecordProcessing.RecordType RcrdType = RecordType.RF_Test_400_900;
public const string WorkflowStep = "rf_power";
public const string DfltWorkplaceName = "RF Test";
#elif COMM_TEST
public RecordProcessing.RecordType RcrdType = RecordType.CommTest;
public const string WorkflowStep = "comm_test";
public const string DfltWorkplaceName = "Comm Test";
#elif FLOWTUBE_TEST_HE
public RecordProcessing.RecordType RcrdType = RecordType.FlowtubeTestHe;
public const string WorkflowStep = "helium_test";
public const string DfltWorkplaceName = "Helium Test";
#elif FLOWTUBE_TEST_AIR
public RecordProcessing.RecordType RcrdType = RecordType.FlowtubeTestAir;
public const string WorkflowStep = "helium_test";
public const string DfltWorkplaceName = "Helium Test";
#elif LASER_NANJING
public RecordProcessing.RecordType RcrdType = RecordType.LaserNanjing;
public const string WorkflowStep = "laser";
public const string DfltWorkplaceName = "Laser 1";
#else
public RecordProcessing.RecordType RcrdType = RecordType.None;
public const string WorkflowStep = "generic_test";
public const string DfltWorkplaceName = "Generic Test";
#endif
const int ActivityMsgsCount = 7;
ActivityEventArgs[] activityEvents; /// Activity messages displayed in the main window
Common.Forms.ModelessForm modelessForm;
NHibernate.ISession dbSession; /// MySQL database session
static OracleConnection oracleConn; /// Oracle database connection (server is in Stara Tura)
#if RF_TEST_400_900
static OracleConnection oracleConn2; /// Oracle database connection for Flexnet ID (server is in Ludwigshafen)
#endif
IList<WorkflowSummary> workflowSummaries; /// Workflows from the database with last step verification information
DateTime lastUpdateOfWorkflows;
RecordProcessing.RecordProcessing recordProcessing;
bool isSensorReadRunning;
int modbusAddress;
Modbus modbus;
System.Windows.Forms.Timer sensorReadTimer;
double[] sensorBuffer;
double[] sensorCoefficients;
int validReadingsCount;
double immediateSensorValue;
double filteredSensorValue;
#region GenericTestDlg constructor, event handlers and utilities
/// <summary>
/// Constructor
/// </summary>
public GenericTestDlg()
{
InitializeComponent();
try
{
string culture = Program.LocalSettings.Language.Replace('_', '-');
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo(culture);
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(culture);
}
catch (Exception exc)
{
string msg = exc.Message;
MessageBox.Show("Selected language is not supported.\nUsing English.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("en");
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en");
}
Localize();
UpdateTitle();
/// Open a modeless form that is closed after initialization and loading the main window
modelessForm = new Common.Forms.ModelessForm("Loading workflows from a database");
new Thread(() => Application.Run(modelessForm)).Start();
activityEvents = new ActivityEventArgs[ActivityMsgsCount];
activityListView.Columns.Add(Strings.Time, 60);
#if FLOWTUBE_TEST_AIR || FLOWTUBE_TEST_HE
activityListView.Columns.Add(Strings.Serial_number, 160);
#else
activityListView.Columns.Add(Strings.Serial_number, 95);
#endif
activityListView.Columns.Add(Strings.Message, 800);
ActivityHandler += delegate(object sndr, ActivityEventArgs args)
{
if (InvokeRequired) Invoke(new EventHandler<ActivityEventArgs>(DoOnActivity), sndr, args);
else DoOnActivity(sndr, args);
};
isSensorReadRunning = false;
immediateSensorValue = 0;
filteredSensorValue = 0;
ReadProcesses_RegisterWorkplace_Etc();
}
void Localize()
{
messageLabel.Text = string.IsNullOrEmpty(Program.LocalSettings.Workplace) ? "Laser" : Program.LocalSettings.Workplace;
startButton.Text = Strings.Start;
stopButton.Text = Strings.Stop;
settingsButton.Text = Strings.Settings;
logoutButton.Text = Strings.Logout;
}
private void GenericTestDlg_Load(object sender, EventArgs e)
{
Settings2UI();
StartSpoolProcessing();
UpdateStartStopButtons();
if (Program.LocalSettings.DoReadSensor)
{
StarSensorReading();
}
if (modelessForm != null) modelessForm.CloseForm(); /// Close the modeless information form
}
private void startButton_Click(object sender, EventArgs e)
{
StartSpoolProcessing();
UpdateStartStopButtons();
}
private void stopButton_Click(object sender, EventArgs e)
{
StopSpoolProcessing();
UpdateStartStopButtons();
}
private void settingsButton_Click(object sender, EventArgs e)
{
if (new LoginDlg(Program.SettingsAccessLevel, this).ShowDialog() == DialogResult.OK)
{
/// Logged in at 'TraceabilityManagement' level
CurrentUser.Restore(this); /// Restore the original user (= tester)
string oriWorkplace = Program.LocalSettings.Workplace;
///
if (new SettingsDlg().ShowDialog() == DialogResult.OK)
{
if (Program.LocalSettings.Workplace != oriWorkplace)
{
UpdateTitle();
TracingDB.UnregisterWorkplaceObsolete(dbSession, oriWorkplace);
TracingDB.RegisterWorkplaceObsolete(dbSession,
Program.LocalSettings.Workplace,
CurrentUser.UserName(),
"1.2.3.4",
"<multiple>",
WorkflowStep,
DateTime.Now + new TimeSpan(365, 0, 0, 0));
dbSession.Flush();
}
}
}
}
private void GenericTestDlg_FormClosing(object sender, FormClosingEventArgs e)
{
DialogResult dr = MessageBox.Show("Naozaj chcete zavrieť tento program?" + Environment.NewLine +
"Výsledky sa nebudú ukladať do Oracle DB a tlačiť na tlačiarni",
"Upozornenie",
MessageBoxButtons.YesNo,
MessageBoxIcon.Exclamation);
if (dr == DialogResult.Yes)
{
if (isSensorReadRunning)
{
StopSensorReading();
}
UI2Settings();
TracingDB.UnregisterWorkplaceObsolete(dbSession, Program.LocalSettings.Workplace);
dbSession.Flush();
StopSpoolProcessing();
}
else
{
e.Cancel = true;
}
}
/// <summary>
/// Load UI settings from 'LocalSettings'
/// </summary>
void Settings2UI()
{
LocalSettings ls = Program.LocalSettings;
WindowState = (ls != null && ls.MainWndMaximized) ? FormWindowState.Maximized : FormWindowState.Normal;
Width = (ls != null && ls.MainWndWidth > 0) ? ls.MainWndWidth : 1000;
Height = (ls != null && ls.MainWndHeight > 0) ? ls.MainWndHeight : 260;
Left = (ls != null && ls.MainWndLeft > 0) ? ls.MainWndLeft : 50;
Top = (ls != null && ls.MainWndTop > 0) ? ls.MainWndTop : 50;
if (ls.DoReadSensor)
{
sensorNameLabel.Text = ls.SensorName;
immediateSensorValueLabel.Text = string.Empty;
filteredSensorValueLabel.Text = string.Empty;
}
else
{
splitContainer1.SplitterDistance = 0;
}
}
/// <summary>
/// Save UI settings to 'LocalSettings'
/// </summary>
void UI2Settings()
{
bool isMaximized = (WindowState == FormWindowState.Maximized);
int left = (WindowState == FormWindowState.Normal) ? Location.X : RestoreBounds.Left;
int top = (WindowState == FormWindowState.Normal) ? Location.Y : RestoreBounds.Top;
int width = (WindowState == FormWindowState.Normal) ? Size.Width : RestoreBounds.Width;
int height = (WindowState == FormWindowState.Normal) ? Size.Height : RestoreBounds.Height;
LocalSettings ls = Program.LocalSettings;
if (ls != null && (ls.MainWndMaximized != isMaximized ||
ls.MainWndLeft != left ||
ls.MainWndTop != top ||
ls.MainWndWidth != width ||
ls.MainWndHeight != height))
{
/// At least one MainWnd dimension differs => Update local settings and save them
ls.MainWndMaximized = isMaximized;
ls.MainWndLeft = left;
ls.MainWndTop = top;
ls.MainWndWidth = width;
ls.MainWndHeight = height;
ls.Save();
}
}
void UpdateStartStopButtons()
{
bool r = (recordProcessing != null) ? recordProcessing.Running : false;
startButton.Enabled = !r;
stopButton.Enabled = r;
}
void StartSpoolProcessing()
{
if (recordProcessing != null)
{
recordProcessing.StartProcessing();
OnActivity(null, new ActivityEventArgs(Program.Version, Strings.Processing_tester_results_started, ActivityCode.StartStop, Color.Yellow, 5000, Color.LightGoldenrodYellow));
}
}
void StopSpoolProcessing()
{
if (recordProcessing != null)
{
recordProcessing.StopProcessing();
OnActivity(null, new ActivityEventArgs(Program.Version, Strings.Processing_tester_results_was_stopped, ActivityCode.StartStop, Color.Yellow, 5000, Color.LightGoldenrodYellow));
}
}
#endregion GenericTestDlg constructor, event handlers and utilities
#region Sensor processing
void StarSensorReading()
{
const int IntervalSec = 5;
LocalSettings ls = Program.LocalSettings;
try
{
int bufferLen = Math.Max(1, 60 * (int)ls.SensorFilterTimeMinutes / IntervalSec);
sensorBuffer = new double[bufferLen];
sensorCoefficients = new double[bufferLen];
validReadingsCount = 0;
double sum = 0;
for (int i = 0; i < bufferLen; i++)
{
sensorCoefficients[i] = Math.Cos((i * Math.PI) / (2 * bufferLen));
sum += sensorCoefficients[i];
}
for (int i = 0; i < bufferLen; i++)
{
sensorCoefficients[i] /= sum; /// normalize
}
modbusAddress = (ls.SensorAddress >= 1) && (ls.SensorAddress <= 254) ? ls.SensorAddress : 0;
var modbusCfg = new ModbusCfg
{
Name = "Modbus",
ParentName = string.Empty,
ComPortNr = ls.SensorComPortNr,
BaudRate = 9600,
Parity = System.IO.Ports.Parity.None,
DataBits = 8,
StopBits = System.IO.Ports.StopBits.One,
Handshake = System.IO.Ports.Handshake.None
};
modbus = new Modbus(modbusCfg);
modbus.Initialize();
sensorReadTimer = new System.Windows.Forms.Timer();
sensorReadTimer.Interval = 1000 * IntervalSec; /// Convert interval to ms
sensorReadTimer.Tick += (Object s, EventArgs e) => { ReadSensor(); };
sensorReadTimer.Start();
modbus.SendMessage((byte)modbusAddress, (byte)TBF.Rig.Modbus.Function.ReadHoldingRegisters, (ushort)0x0030, (ushort)2, "Temperature");
isSensorReadRunning = true;
}
catch (Exception exc)
{
MessageBox.Show(string.Format("Cannot read sensor {0}, COM{1}, address {2}\r\n{3}", ls.SensorName, ls.SensorComPortNr, ls.SensorAddress, exc.Message));
}
}
void StopSensorReading()
{
if (isSensorReadRunning)
{
sensorReadTimer.Stop();
if (modbus != null) modbus.StopDevice();
}
}
void ReadSensor()
{
if (modbus != null)
{
modbus.RunDeviceBefore();
if (modbus.ReceivedTelegrams[modbusAddress].Count > 0)
{
byte[] telegram = modbus.ReceivedTelegrams[modbusAddress].Dequeue();
if (telegram.Length == 9 && telegram[1] == 3 && telegram[2] == 4)
{
int intValue = (int)telegram[3] * 256 + (int)telegram[4];
immediateSensorValue = (double)intValue / 10.0;
filteredSensorValue = UpdateBufferAndGetFilteredValue(immediateSensorValue, sensorBuffer, sensorCoefficients, ref validReadingsCount);
immediateSensorValueLabel.Text = string.Format("{0:F1} °C", immediateSensorValue);
filteredSensorValueLabel.Text = string.Format("{0:F1} °C", filteredSensorValue);
}
}
modbus.SendMessage((byte)modbusAddress, (byte)TBF.Rig.Modbus.Function.ReadHoldingRegisters, (ushort)0x0030, (ushort)2, "Temperature");
}
}
double UpdateBufferAndGetFilteredValue(double value, double[] buffer, double[] coefficients, ref int validCount)
{
if (validCount < buffer.Length)
{
for (int i = validCount; i > 0; i--) buffer[i] = buffer[i - 1];
buffer[0] = value;
validCount++;
double sumOfCoefficients = 0;
double sumOfValues = 0;
for (int i = 0; i < validCount; i++)
{
sumOfCoefficients += coefficients[i];
sumOfValues += (coefficients[i] * buffer[i]);
}
return sumOfValues / sumOfCoefficients;
}
else
{
for (int i = buffer.Length - 1; i > 0; i--) buffer[i] = buffer[i - 1];
buffer[0] = value;
double sumOfValues = 0;
for (int i = 0; i < validCount; i++)
{
sumOfValues += (coefficients[i] * buffer[i]);
}
return sumOfValues;
}
}
#endregion Sensor processing
#region Displaying activities and timer
public static event EventHandler<ActivityEventArgs> ActivityHandler;
/// <summary>
/// Called from the state machine when test process data change and UI needs to be updated.
/// </summary>
public static void OnActivity(object sender, ActivityEventArgs data)
{
if (ActivityHandler == null) return;
try { ActivityHandler(sender, data); }
catch (Exception) { }
}
private static System.Windows.Forms.Timer timer;
private static Color delayedFadedColor;
private static string messageText;
///
private void DoOnActivity(object sender, ActivityEventArgs args)
{
#if FLOWTUBE_TEST_AIR || FLOWTUBE_TEST_HE
string msg = string.Format("{0} - {1}", (string.IsNullOrEmpty(args.SN) ? "00000000000000000000" : args.SN), args.Message);
string rslt = string.Format("{0} ; {1}", (string.IsNullOrEmpty(args.SN) ? "00000000000000000000" : args.SN), args.Message);
#else
string msg = string.Format("{0} - {1}", (string.IsNullOrEmpty(args.SN) ? "000000000000" : args.SN), args.Message);
string rslt = string.Format("{0} ; {1}", (string.IsNullOrEmpty(args.SN) ? "000000000000" : args.SN), args.Message);
#endif
/// Logging level depends on data.IsError value
if (args.ActivityCode == ActivityCode.StartStop)
{
/// Activity: Start/Stop
log.Fatal(msg);
}
else if (args.ActivityCode == ActivityCode.Passed)
{
/// Activity: Passed
log.Info(msg);
results.Fatal(rslt);
}
else if (args.ActivityCode == ActivityCode.Failed)
{
/// Activity: Failed
Console.Beep(ErrorBeepFrequency, ErrorBeepDuration);
if (Program.LocalSettings.MaximizeWindowOnError)
{
/// Maximize windows and gain focus here
this.WindowState = FormWindowState.Maximized;
this.TopMost = true;
this.Focus();
this.BringToFront();
}
log.Error(msg);
results.Fatal(rslt);
badResults.Fatal(rslt);
}
else
{
/// Activity: Undefined
return;
}
/// Shift activities in FIFO bufer, nw item is at index 0 (at the topP
for (int i = ActivityMsgsCount - 1; i > 0; i--)
{
activityEvents[i] = activityEvents[i - 1];
}
activityEvents[0] = args;
messageLabel.Text = string.Format("{0} {1}", (string.IsNullOrEmpty(args.SN) ? "000000000000" : args.SN), args.Message);
horizSplitContainer.Panel1.BackColor = args.Color;
UpdateMultiLineActivityLog();
/// Start a timer
if (timer == null)
{
timer = new System.Windows.Forms.Timer();
timer.Tick += (s, e) => { DelayTimerExpired(); };
}
delayedFadedColor = args.FadedColor;
messageText = messageLabel.Text;
timer.Interval = args.Interval;
timer.Start();
}
void UpdateMultiLineActivityLog()
{
activityListView.Items.Clear();
for (int i = 0; i < ActivityMsgsCount; i++)
{
if (activityEvents[i] != null)
{
ListViewItem lvi = new ListViewItem(activityEvents[i].TimeStamp.ToLongTimeString());
lvi.SubItems.Add(string.IsNullOrEmpty(activityEvents[i].SN) ? "000000000000" : activityEvents[i].SN);
lvi.SubItems.Add(activityEvents[i].Message);
lvi.BackColor = activityEvents[i].FadedColor;
activityListView.Items.Add(lvi);
}
}
}
void DelayTimerExpired()
{
/// Delayed action
if (messageLabel.Text == messageText)
{
horizSplitContainer.Panel1.BackColor = delayedFadedColor;
}
timer.Stop();
timer.Enabled = false;
}
#endregion Displaying activities and timer
/// <summary>
/// Called from the main window constructor on program start-up
/// </summary>
void ReadProcesses_RegisterWorkplace_Etc()
{
///
/// Loads processes from the database.
/// In case of problems (missing database) makes it possible to create a new one.
///
bool testResultsFolderExists = false;
DialogResult settingsDR = DialogResult.OK;
do
{
if (settingsDR == DialogResult.OK)
{
testResultsFolderExists = Directory.Exists(Program.LocalSettings.TestResultsFolder);
if (!testResultsFolderExists)
{
string failedMsg = string.Format(Strings.Opening_folder_0_failed, Program.LocalSettings.TestResultsFolder);
log.Fatal(failedMsg);
DialogResult rslt = MessageBox.Show(failedMsg + Environment.NewLine +
Strings.Do_you_want_to_change_settings,
Strings.Warning,
MessageBoxButtons.YesNo,
MessageBoxIcon.Exclamation);
if (rslt != DialogResult.Yes)
{
/// Settings ware not changed -> exit
throw new QuitAppException(failedMsg);
}
settingsDR = new SettingsDlg().ShowDialog();
}
}
if (settingsDR == DialogResult.OK)
{
try
{
dbSession = TracingDB.CreateSession(Program.LocalSettings.ConnectionString);
workflowSummaries = TracingDB.ReadWorkflowSummariesFromDB(dbSession, WorkflowStep);
lastUpdateOfWorkflows = DateTime.Now;
}
catch (Exception exc)
{
log.FatalFormat("{0}:{1}{2}", Strings.Opening_database_failed, Environment.NewLine, exc.Message);
DialogResult rslt = MessageBox.Show(Strings.Opening_database_failed +
Environment.NewLine + Environment.NewLine +
exc.Message +
Environment.NewLine + Environment.NewLine +
Strings.Do_you_want_to_change_settings,
Strings.Warning,
MessageBoxButtons.YesNo,
MessageBoxIcon.Exclamation);
if (rslt != DialogResult.Yes)
{
/// Settings ware not changed -> exit
throw new QuitAppException(Strings.Opening_database_failed);
}
settingsDR = new SettingsDlg().ShowDialog();
}
}
if ((settingsDR == DialogResult.OK) && Program.LocalSettings.DoSaveTestResultToOracle && (Program.LocalSettings.OracleMode != Mode.Debug))
{
#if RF_TEST || RF_TEST_400_900
///
/// Connect to Oracle database in Stara Tura
///
try
{
if ((Program.LocalSettings.OracleMode == Mode.Production) || (Program.LocalSettings.OracleMode == Mode.NoWritesToDB))
{
oracleConn = new OracleConnection("Data Source=STARA01.WORLD;User Id=deltachef;Password=deltachef;");
}
else if (Program.LocalSettings.OracleMode == Mode.Test)
{
oracleConn = new OracleConnection("Data Source=STARA_TEST.WORLD;User Id=deltachef;Password=deltachef;");
}
/// Do something with the database to see if the connection works well
oracleConn.Open();
string rslt = "none";
OracleCommand cmd = new OracleCommand("SELECT standort FROM anbieter_sd WHERE anbid = 4", oracleConn);
OracleDataReader dr = cmd.ExecuteReader();
if (dr.Read()) rslt = dr.GetString(0);
dr.Close();
oracleConn.Close();
}
catch (Exception exc)
{
log.FatalFormat("{0}:{1}{2}", Strings.Opening_database_failed, Environment.NewLine, exc.Message);
DialogResult rslt = MessageBox.Show(Strings.Opening_database_failed +
Environment.NewLine + Environment.NewLine +
exc.Message +
Environment.NewLine + Environment.NewLine +
Strings.Do_you_want_to_change_settings,
Strings.Warning,
MessageBoxButtons.YesNo,
MessageBoxIcon.Exclamation);
if (rslt != DialogResult.Yes)
{
/// Settings ware not changed -> exit
throw new QuitAppException(Strings.Opening_database_failed);
}
settingsDR = new SettingsDlg().ShowDialog();
}
#endif
#if RF_TEST_400_900
///
/// Connect to Oracle database in Ludwigshafen
///
try
{
oracleConn2 = new OracleConnection("Data Source=ALDT01.WORLD;User Id=deltachef;Password=deltachef;");
/// Do something with the database to see if the connection works well
oracleConn2.Open();
string rslt = "none";
OracleCommand cmd = new OracleCommand("SELECT pcb_number " +
"FROM ip_flexnet_functional_test_pd " +
"WHERE flexnet_uid = '330024' " +
"ORDER BY changedate DESC", oracleConn2);
OracleDataReader dr = cmd.ExecuteReader();
if (dr.Read()) rslt = dr.GetString(0);
dr.Close();
oracleConn2.Close();
}
catch (Exception exc)
{
log.FatalFormat("{0}:{1}{2}", Strings.Opening_database_failed, Environment.NewLine, exc.Message);
DialogResult rslt = MessageBox.Show("LUDWIGSHAFEN ORACLE DB" + Environment.NewLine + Strings.Opening_database_failed +
Environment.NewLine + Environment.NewLine + exc.Message,
Strings.Error,
MessageBoxButtons.OK,
MessageBoxIcon.Exclamation);
/// Settings were not changed -> exit
throw new QuitAppException(Strings.Something_failed);
}
#endif
}
}
while (settingsDR != DialogResult.Cancel && (dbSession == null || !testResultsFolderExists));
if (settingsDR == DialogResult.Cancel)
{
/// Settings were not changed -> exit
throw new QuitAppException(Strings.Something_failed);
}
if (!string.IsNullOrEmpty(Program.LocalSettings.UsersDBConnString))
{
CurrentUser.LocalUsersDB = new DBSettings(DBType.MySql, Program.LocalSettings.UsersDBConnString);
}
UpdateTitle();
TracingDB.RegisterWorkplaceObsolete(dbSession,
Program.LocalSettings.Workplace,
CurrentUser.UserName(),
"1.2.3.4",
"<multiple>",
WorkflowStep,
DateTime.Now + new TimeSpan(15, 0, 0, 0)); /// Registration is valid approx. 2 weeks
/// Activate processing of test results created by a thirdparty test program
switch (RcrdType)
{
case RecordType.RF_Test:
case RecordType.RF_Test_400_900:
recordProcessing = new RecordProcessing.RecordProcessing(RcrdType,
RecordPostproc.Compress,
Program.LocalSettings.TestResultsFolder, false, "*.xml",
Program.LocalSettings.ArchiveFolder, true);
break;
case RecordType.CommTest:
recordProcessing = new RecordProcessing.RecordProcessing(RecordType.CommTest,
RecordPostproc.None,
Program.LocalSettings.TestResultsFolder, true, "*.log");
break;
case RecordType.FlowtubeTestHe:
recordProcessing = new RecordProcessing.RecordProcessing(RecordType.FlowtubeTestHe,
RecordPostproc.Move,
Program.LocalSettings.TestResultsFolder, false, "*.csv",
Program.LocalSettings.ArchiveFolder, true);
break;
case RecordType.FlowtubeTestAir:
/// Format of records and processing is similar to RecordType.RF_Test
recordProcessing = new RecordProcessing.RecordProcessing(RecordType.FlowtubeTestAir,
RecordPostproc.Compress,
Program.LocalSettings.TestResultsFolder, false, "*.xml",
Program.LocalSettings.ArchiveFolder, true);
break;
case RecordType.LaserNanjing:
recordProcessing = new RecordProcessing.RecordProcessing(RecordType.LaserNanjing,
RecordPostproc.Move,
Program.LocalSettings.TestResultsFolder, false, "*.csv",
Program.LocalSettings.ArchiveFolder, true);
break;
case RecordType.None:
default:
recordProcessing = null;
break;
}
if (recordProcessing != null)
{
recordProcessing.SubmitRecordHandler += delegate(object sender, RecordProcessing.SubmitRecordEventArgs args)
{
if (InvokeRequired)
{
Invoke(new EventHandler<RecordProcessing.SubmitRecordEventArgs>(ProcessOneRecord), sender, args);
}
else
{
ProcessOneRecord(sender, args);
}
};
}
}
/// <summary>
/// Submits a reference part code from a record from a 3-rd party program
/// </summary>
/// <param name="sender"></param>
/// <param name="args">Argument containing record fr</param>
void ProcessOneRecord(object sender, RecordProcessing.SubmitRecordEventArgs args)
{
IRecord testerRecord = args.Record;
VerifState verifState = VerifState.Undefined;
if ((testerRecord == null) || string.IsNullOrEmpty(testerRecord.SN) || (testerRecord.SN.Length < 3))
{
/// PCB number is missing or too short
verifState = VerifState.SNisMissing;
OnActivity(null, new ActivityEventArgs(string.Empty, Strings.Serial_number_is_missing, ActivityCode.Failed, Color.Orange, 5000, Color.Wheat));
return;
}
#if RF_TEST_400_900
try
{
///
/// Replace Flexnet UID by PCB Number from Oracle database
///
string pcbNrFromFlexnetUid = string.Empty;
oracleConn2.Open();
OracleCommand cmd = new OracleCommand(string.Format("SELECT pcb_number " +
"FROM ip_flexnet_functional_test_pd " +
"WHERE flexnet_uid = '{0}' " +
"ORDER BY changedate DESC", testerRecord.SN),
oracleConn2);
OracleDataReader dr = cmd.ExecuteReader();
if (dr.Read()) pcbNrFromFlexnetUid = dr.GetString(0);
dr.Close();
oracleConn2.Close();
if (!string.IsNullOrEmpty(pcbNrFromFlexnetUid)) testerRecord.SN = pcbNrFromFlexnetUid;
}
catch (Exception)
{
}
#endif
if (Program.LocalSettings.DoCheckSNsValidity &&
(Program.LocalSettings.ValidSNPrefixes != null)
&& !Program.LocalSettings.ValidSNPrefixes.Contains(testerRecord.SN.Substring(0, 3)))
{
/// PCB number did not pass a validity check (is not on a list of valid PCB numbers)
verifState = VerifState.SNisInvalid;
OnActivity(null, new ActivityEventArgs(testerRecord.SN, Strings.Serial_number_is_invalid, ActivityCode.Failed, Color.Orange, 5000, Color.Wheat));
return;
}
///
/// A valid serial number is available => proceed
///
ITransaction transaction = null;
bool savingToTracingDBFailed = false; /// Writing to tracoing DB failed (equipment error)
bool verificationFailed = false; /// Reading/writing from/to tracing DB OK, but verification failed (product error)
try
{
///
/// Tracing DB read/write is done inside this try/catch
///
transaction = dbSession.BeginTransaction();
/// Get a process of the last reference record with this PCB number
var refRecord = TracingDB.FindReferenceRecord(dbSession, testerRecord.SN, 1);
WorkflowSummary wSum = (refRecord == null) ? null :
workflowSummaries.FirstOrDefault(x => x.Workflow.Name == refRecord.Workflow);
if (refRecord == null || wSum == null)
{
verifState = VerifState.NoRefRecordOrNoMatchingWorkflow;
verificationFailed = true;
savingToTracingDBFailed = false;
}
else
{
if (!Program.LocalSettings.DoCheckPreviousTracingRecords)
{
/// The process was determined but checking previous records is disbled => everything is OK so far
verifState = VerifState.VerificationIsDisabled;
verificationFailed = false;
}
else
{
/// Process is known AND the system is checking previous records => verify previous step
StepRecord prevStep = refRecord.StepRecords.FirstOrDefault(x => (x.Workstep == wSum.PreviousWorkstepName && x.Result == 0));
verificationFailed = (prevStep == null);
verifState = (prevStep != null) ? VerifState.VerificationPassed : VerifState.VerificationFailed;
}
/// result: 0=OK, 1=test failed, 2=OK but previous step is missing, 3=failed and previous step is missing
int result = ((testerRecord.Status == Status.Passed) ? 0 : 1) + ((verifState == VerifState.VerificationFailed) ? 2 : 0);
string workplace = Program.LocalSettings.Workplace;
string user = "user";
///
StepRecord stepRecord = new StepRecord(refRecord, wSum.WorkstepName, workplace, user, result);
refRecord.Timestamp = stepRecord.Timestamp;
refRecord.StepRecords.Add(stepRecord);
dbSession.SaveOrUpdate(stepRecord);
dbSession.SaveOrUpdate(refRecord);
transaction.Commit();
savingToTracingDBFailed = false;
}
}
catch (Exception)
{
if ((transaction != null) && !transaction.WasCommitted) transaction.Rollback();
savingToTracingDBFailed = true;
}
///
/// Write the test result to Oracle DB
///
bool savingToOracleDBFailed = false;
if (Program.LocalSettings.DoSaveTestResultToOracle &&
testerRecord.CanSaveRecordToOracle() &&
(Program.LocalSettings.OracleMode != Mode.Debug) &&
(Program.LocalSettings.OracleMode != Mode.NoWritesToDB) &&
(testerRecord.Status != Status.Interrupted))
{
#if RF_TEST
/// Conditions for writing data to Oracle DB are satisfied
savingToOracleDBFailed = !testerRecord.SaveRecordToOracle(oracleConn);
if (savingToOracleDBFailed) log.ErrorFormat("Saving test result to Oracle failed : {0}", testerRecord.ToString());
#elif RF_TEST_400_900
/// Conditions for writing data to Oracle DB are satisfied
savingToOracleDBFailed = !testerRecord.SaveRecordToOracle(oracleConn2);
if (savingToOracleDBFailed) log.ErrorFormat("Saving test result to Oracle failed : {0}", testerRecord.ToString());
#endif
}
///
/// Print the test result on a printer
///
bool printingFailed = false;
if (Program.LocalSettings.DoPrintLabels && testerRecord.CanPrintRecord()
&& (!Program.LocalSettings.DoPrintGoodLabelsOnly ||
!(savingToTracingDBFailed || verificationFailed || savingToOracleDBFailed || testerRecord.Status != Status.Passed)))
{
/// Conditions for printing results are satisfied
#if RF_TEST || RF_TEST_400_900
/// Get battery info from Tracing database
if ((proc != null) && (testerRecord is RecordProcessing.Records.RFTestRecord))
{
RecordProcessing.Records.RFTestRecord rfRecord = testerRecord as RecordProcessing.Records.RFTestRecord;
foreach (var part in proc.Parts)
{
if (!string.IsNullOrEmpty(part.OraDBType))
{
string[] oraItems = part.OraDBType.Split(new char[] { ' ' });
string oraType = oraItems[0];
string oraDescr = (oraItems.Length > 1) ? oraItems[1] : string.Empty;
if ((oraType == "Batt") || (oraType == "Batt1") || (oraType == "Batt2"))
{
rfRecord.BattSapPartNr = part.Name;
rfRecord.BattSupplier = oraDescr; /// Should be "TADIRAN" or "VITZROCELL"
/// Prepare battery producer information to be printed on labels
if (rfRecord.BattSupplier.ToUpper() == "VITZROCELL") rfRecord.PrintedInfo = "Vi";
else if (rfRecord.BattSupplier.ToUpper() == "TADIRAN") rfRecord.PrintedInfo = "T";
else rfRecord.PrintedInfo = "-";
}
//if (oraType == "Flowtube")
//{
// rfRecord.FlowtubeSapPartNr = part.Name;
// rfRecord.IsPorexFlowtube = Program.LocalSettings.DoCheckPorexSapNumbers
// && !string.IsNullOrEmpty(Program.LocalSettings.PorexSapNumbers)
// && Program.LocalSettings.PorexSapNumbers.Contains(part.Name);
//}
}
}
}
#endif
printingFailed = !testerRecord.PrintRecord();
if (printingFailed) log.ErrorFormat("Printing result failed : {0}", testerRecord.ToString());
}
///
/// Display the test result and related activity on the screen.
/// Process the most severe errors first.
///
if (verificationFailed)
{
/// Verification is enabled, but a record from the previous workplace is missing
OnActivity(null, new ActivityEventArgs(testerRecord.SN, Strings.Previous_workflow_step_is_missing_or_failed, ActivityCode.Failed, Color.Blue, 5000, Color.LightBlue));
}
else if (savingToTracingDBFailed)
{
OnActivity(null, new ActivityEventArgs(testerRecord.SN, Strings.Saving_to_Tracing_DB_failed, ActivityCode.Failed, Color.Orange, 5000, Color.Wheat));
}
else if (savingToOracleDBFailed)
{
OnActivity(null, new ActivityEventArgs(testerRecord.SN, Strings.Saving_to_Oracle_DB_failed, ActivityCode.Failed, Color.Orange, 5000, Color.Wheat));
}
else if (printingFailed)
{
OnActivity(null, new ActivityEventArgs(testerRecord.SN, Strings.Printing_failed, ActivityCode.Failed, Color.Orange, 5000, Color.Wheat));
}
else if (testerRecord.Status != Status.Passed)
{
/// Test result is 'Failed' or 'Interrupted'
OnActivity(null, new ActivityEventArgs(testerRecord.SN, string.Format(Strings.Test_failed_0, testerRecord.ResultStr), ActivityCode.Failed, Color.Red, 5000, Color.Pink));
}
else
{
/// Test passed
OnActivity(null, new ActivityEventArgs(testerRecord.SN, string.Format(Strings.OK_0, testerRecord.ResultStr), ActivityCode.Passed, Color.Green, 5000, Color.LightGreen));
}
}
private void logoutButton_Click(object sender, EventArgs e)
{
///
/// User login
///
while (true)
{
if (new SharedDatabase.Forms.LoginDlg().ShowDialog() == DialogResult.OK)
{
break;
}
}
UpdateTitle();
//wplaceRegistration.UpdateRegistration(dbSession,
// Program.LocalSettings.WorkplaceId,
// Users.GlobalData.CurrentUser.UserName,
// "1.2.3.4",
// (currentProcess != null) ? currentProcess.Name : string.Empty,
// (currentWorkstep != null) ? currentWorkstep.Name : string.Empty,
// DateTime.Now + new TimeSpan(8, 0, 0));
}
void UpdateTitle()
{
Text = string.Format("{0} v.{1} ({2}, {3})", DfltWorkplaceName, Program.Version, Program.LocalSettings.Workplace, CurrentUser.UserName());
}
}
}