1077 lines
49 KiB
C#
1077 lines
49 KiB
C#
|
|
///
|
|||
|
|
/// Copyright (c) 2019 Sensus Slovensko a.s.
|
|||
|
|
///
|
|||
|
|
using System;
|
|||
|
|
using System.Collections.Generic;
|
|||
|
|
using System.Drawing;
|
|||
|
|
using System.IO;
|
|||
|
|
using System.IO.Ports;
|
|||
|
|
using System.Threading;
|
|||
|
|
using System.Windows.Forms;
|
|||
|
|
using log4net;
|
|||
|
|
using TracingDB;
|
|||
|
|
using TracingDB.Entities;
|
|||
|
|
using Devices.Modbus;
|
|||
|
|
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";
|
|||
|
|
#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
|
|||
|
|
|
|||
|
|
|
|||
|
|
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<Process> processes; /// Processes from the database
|
|||
|
|
Dictionary<int, Process> processDictionary; /// Maps a process Id to a process
|
|||
|
|
Dictionary<int, IList<Workstep>> workstepsDictionary; /// Maps a process Id to worksteps with name "RF_Power" (Count = 0 or 1)
|
|||
|
|
static Dictionary<int, TracingDB.ScanVerificationInfo> verificationInfos;
|
|||
|
|
/// Maps process Id to verification info
|
|||
|
|
DateTime lastUpdateOfProcesses;
|
|||
|
|
|
|||
|
|
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()
|
|||
|
|
{
|
|||
|
|
/// Open a modeless form that is closed after initialization and loading the main window
|
|||
|
|
new Thread(() => Application.Run(new TracingDB.Forms.ModelessForm()
|
|||
|
|
{
|
|||
|
|
Title = "",
|
|||
|
|
Message = "Načítavanie procesov z databázy",
|
|||
|
|
BackgroundColor = Color.LightGreen,
|
|||
|
|
FontFamily = "Arial",
|
|||
|
|
FontSize = 14,
|
|||
|
|
FontStyle = FontStyle.Regular,
|
|||
|
|
})).Start();
|
|||
|
|
|
|||
|
|
InitializeComponent();
|
|||
|
|
|
|||
|
|
UpdateTitle();
|
|||
|
|
|
|||
|
|
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();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void GenericTestDlg_Load(object sender, EventArgs e)
|
|||
|
|
{
|
|||
|
|
Settings2UI();
|
|||
|
|
StartSpoolProcessing();
|
|||
|
|
UpdateStartStopButtons();
|
|||
|
|
if (Program.LocalSettings.DoReadSensor)
|
|||
|
|
{
|
|||
|
|
StarSensorReading();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
TracingDB.Forms.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)
|
|||
|
|
{
|
|||
|
|
Users.Entities.User oriUser = Users.GlobalData.CurrentUser; /// Save the original user (= tester)
|
|||
|
|
|
|||
|
|
if (new Users.Forms.LoginDlg(Program.SettingsAccessLevel).ShowDialog() == DialogResult.OK)
|
|||
|
|
{
|
|||
|
|
/// Logged in at 'TraceabilityManagement' level
|
|||
|
|
|
|||
|
|
Users.GlobalData.CurrentUser = oriUser; /// Restore the original user (= tester)
|
|||
|
|
|
|||
|
|
string oriWorkplace = Program.LocalSettings.Workplace;
|
|||
|
|
///
|
|||
|
|
if (new SettingsDlg().ShowDialog() == DialogResult.OK)
|
|||
|
|
{
|
|||
|
|
if (Program.LocalSettings.Workplace != oriWorkplace)
|
|||
|
|
{
|
|||
|
|
UpdateTitle();
|
|||
|
|
|
|||
|
|
DB.UnregisterWorkplaceObsolete(dbSession, oriWorkplace);
|
|||
|
|
DB.RegisterWorkplaceObsolete(dbSession,
|
|||
|
|
Program.LocalSettings.Workplace,
|
|||
|
|
Users.GlobalData.GetCurrentUserName(),
|
|||
|
|
"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();
|
|||
|
|
DB.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",
|
|||
|
|
ClassName = "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)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)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 TracingDB.QuitAppException(failedMsg);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
settingsDR = new SettingsDlg().ShowDialog();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (settingsDR == DialogResult.OK)
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
dbSession = DB.CreateSession(Program.LocalSettings.ConnectionString);
|
|||
|
|
processes = TracingDB.DB.ReadWorkflowsFromDB(dbSession, WorkflowStep, out processDictionary, out workstepsDictionary, out verificationInfos);
|
|||
|
|
lastUpdateOfProcesses = 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("Niečo sa nepodarilo");
|
|||
|
|
}
|
|||
|
|
#endif
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
while (settingsDR != DialogResult.Cancel && (dbSession == null || !testResultsFolderExists));
|
|||
|
|
|
|||
|
|
if (settingsDR == DialogResult.Cancel)
|
|||
|
|
{
|
|||
|
|
/// Settings were not changed -> exit
|
|||
|
|
throw new QuitAppException("Niečo sa nepodarilo");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!string.IsNullOrEmpty(Program.LocalSettings.UsersDBConnString))
|
|||
|
|
{
|
|||
|
|
Users.GlobalData.UsersDB = new Users.DBSettings(Users.Entities.DBType.MySql, Program.LocalSettings.UsersDBConnString);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
UpdateTitle();
|
|||
|
|
|
|||
|
|
DB.RegisterWorkplaceObsolete(dbSession,
|
|||
|
|
Program.LocalSettings.Workplace,
|
|||
|
|
Users.GlobalData.GetCurrentUserName(),
|
|||
|
|
"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.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;
|
|||
|
|
Process proc = null;
|
|||
|
|
bool readingFromTracingDBFailed = false; /// Reading form tracing DB failed (equipment error)
|
|||
|
|
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
|
|||
|
|
proc = DB.GetWorkflow(dbSession, testerRecord.SN);
|
|||
|
|
|
|||
|
|
/// Check if a record from the previous workplace exists
|
|||
|
|
if (proc == null)
|
|||
|
|
{
|
|||
|
|
/// Any previous reference record with this s/n is missing => process cannot be determined
|
|||
|
|
verifState = VerifState.NoRecordAtAll;
|
|||
|
|
}
|
|||
|
|
else if (!Program.LocalSettings.DoCheckPreviousTracingRecords)
|
|||
|
|
{
|
|||
|
|
/// The process was determined but checking previous records is disbled => everything is OK so far
|
|||
|
|
verifState = VerifState.VerificationIsDisabled;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
/// Process is known AND the system is checking previous records => verify previous step
|
|||
|
|
|
|||
|
|
/// Get an appropriate verification info
|
|||
|
|
TracingDB.ScanVerificationInfo verInfo;
|
|||
|
|
bool verInfoObtained = verificationInfos.TryGetValue(proc.Id, out verInfo);
|
|||
|
|
if (!verInfoObtained && (DateTime.Now - lastUpdateOfProcesses) > new TimeSpan(0, 5, 0))
|
|||
|
|
{
|
|||
|
|
/// No verification info was obtained and more then 5 minutes elapsed => read processes again
|
|||
|
|
processes = DB.ReadWorkflowsFromDB(dbSession, WorkflowStep, out processDictionary, out workstepsDictionary, out verificationInfos);
|
|||
|
|
lastUpdateOfProcesses = DateTime.Now;
|
|||
|
|
verInfoObtained = verificationInfos.TryGetValue(proc.Id, out verInfo);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!verInfoObtained)
|
|||
|
|
{
|
|||
|
|
/// No verification info for the process obtained from the reference record found
|
|||
|
|
verifState = VerifState.NoVerificationForThisProcess;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
if (verInfo.VerifyReferencePart)
|
|||
|
|
{
|
|||
|
|
/// Fetch all GOOD reference records with given code
|
|||
|
|
IList<ReferenceRecord> refRecords = dbSession.QueryOver<ReferenceRecord>()
|
|||
|
|
.Where(rr => ((rr.Code == testerRecord.SN) && (rr.Result == 0)))
|
|||
|
|
.And(rr => (rr.Workstep == verInfo.Workstep))
|
|||
|
|
.JoinQueryOver<Workstep>(rr => rr.Workstep)
|
|||
|
|
.Where(ws => (ws.ReferencePart.Id == verInfo.Part.Id))
|
|||
|
|
.List();
|
|||
|
|
|
|||
|
|
verifState = (refRecords.Count > 0) ? VerifState.VerificationPassed : VerifState.VerificationFailed;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
IList<Record> records = dbSession.QueryOver<Record>()
|
|||
|
|
.Where(rec => (rec.Code == testerRecord.SN))
|
|||
|
|
.And(rec => (rec.Part == verInfo.Part))
|
|||
|
|
.List();
|
|||
|
|
|
|||
|
|
verifState = (records.Count > 0) ? VerifState.VerificationPassed : VerifState.VerificationFailed;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
verificationFailed = verifState == VerifState.NoRecordAtAll ||
|
|||
|
|
verifState == VerifState.NoVerificationForThisProcess ||
|
|||
|
|
verifState == VerifState.VerificationFailed;
|
|||
|
|
///
|
|||
|
|
savingToTracingDBFailed = true;
|
|||
|
|
if ((proc != null) && (verifState != VerifState.NoRecordAtAll))
|
|||
|
|
{
|
|||
|
|
IList<Workstep> worksteps;
|
|||
|
|
if (workstepsDictionary.TryGetValue(proc.Id, out worksteps) && (worksteps.Count == 1))
|
|||
|
|
{
|
|||
|
|
/// Save a new reference record to the production tracing DB
|
|||
|
|
dbSession.SaveOrUpdate(new ReferenceRecord(proc, worksteps[0], testerRecord.SN,
|
|||
|
|
Users.GlobalData.GetCurrentUserName(),
|
|||
|
|
Program.LocalSettings.Workplace,
|
|||
|
|
verificationFailed ? 2 : ((testerRecord.Status == Status.Passed) ? 0 : 1)));
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
/// Save a reference record with WORKSTEP=null to the production tracing DB
|
|||
|
|
dbSession.SaveOrUpdate(new ReferenceRecord(proc, null, testerRecord.SN,
|
|||
|
|
Users.GlobalData.GetCurrentUserName(),
|
|||
|
|
Program.LocalSettings.Workplace,
|
|||
|
|
verificationFailed ? 2 : ((testerRecord.Status == Status.Passed) ? 0 : 1)));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
/// Save a reference record with PROCESS=null and WORKSTEP=null to the production tracing DB
|
|||
|
|
savingToTracingDBFailed = true;
|
|||
|
|
dbSession.SaveOrUpdate(new ReferenceRecord(null, null, testerRecord.SN,
|
|||
|
|
Users.GlobalData.GetCurrentUserName(),
|
|||
|
|
Program.LocalSettings.Workplace,
|
|||
|
|
(testerRecord.Status == Status.Passed) ? 0 : 1));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
transaction.Commit();
|
|||
|
|
savingToTracingDBFailed = false;
|
|||
|
|
}
|
|||
|
|
catch (Exception)
|
|||
|
|
{
|
|||
|
|
readingFromTracingDBFailed = !savingToTracingDBFailed;
|
|||
|
|
if ((transaction != null) && !transaction.WasCommitted) transaction.Rollback();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
///
|
|||
|
|
/// 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 || !(readingFromTracingDBFailed || 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 (readingFromTracingDBFailed)
|
|||
|
|
{
|
|||
|
|
OnActivity(null, new ActivityEventArgs(testerRecord.SN, Strings.Reading_from_Tracing_DB_failed, ActivityCode.Failed, Color.Orange, 5000, Color.Wheat));
|
|||
|
|
}
|
|||
|
|
else 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 Users.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, Users.GlobalData.GetCurrentUserName());
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|