tbf/TBF/Rig/TestMethods/S640Communication/S640CommForm.cs
2021-10-26 19:38:09 +02:00

1176 lines
57 KiB
C#

///
/// Copyright (c) 2021 Sensus Slovensko a.s.
///
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.Windows.Forms;
using log4net;
using Common;
using Config.Entities;
using TBF.Resources;
using TBF.Rig.Sequences;
using System.IO;
namespace TBF.Rig.TestMethods.S640Communication
{
public enum CommErr
{
None = 0,
CommFailed, /// 1
HeadDisabledByUser, /// 2
}
///
/// (Program.LocalSettings.OptoHeadsEnabled & (1L << ix))) == 0 . . opto head is disabled in configuration
/// optoheads[ix] == null . . . . . . . . . . . . . . . . . . . . . opto head is not part of the selected sensors path
/// optoHeads[ix].Disabled == true . . . . . . . . . . . . . . . . opto head was disabled by the user
///
public partial class S640CommForm : Form, GenericDevices.IHasCompleted
{
private static readonly ILog log = LogManager.GetLogger(typeof(S640CommForm));
protected static readonly ILog sirtDataLogger = LogManager.GetLogger("SirtData");
public const int UIBoxesCount = 40;
public static Color DisabledColor = Color.DarkGray;
public static Color OptoOKColor = Color.Green;
public static Color OptoNokColor = Color.Red;
public const string StartFileName = "Start.pro";
public const string EndFileName = "Ende.pro";
public const string ErrorFileName = "Error.dat";
enum Step
{
/// Start
WatchOptoHeads,
SaveStartPro,
EnterSNsAndAwaitResponseToStartPro,
AwaitResponseToStartPro,
/// End
EnterSNs,
ConfirmSNsAndRadioAddresses,
SaveEndePro,
AwaitResponseToEndePro,
ConfirmError,
Idle,
}
DateTime startTime;
int startTimeSec;
// Set to 'true' when the form closes
public bool Completed { get { return formCompleted; } }
bool formCompleted;
bool forcedClose; /// Set in the forced close handler
/// <summary> Number of text boxes for serial numbers </summary>
public int WaterMetersCount;
int textBoxesCount;
///
bool[] enabledInConfiguration;
Label[] labels;
PictureBox[] pictures;
TextBox[] messages;
TextBox[] serialNumbers;
CheckBoxImage[] checkBoxes;
int[] ckbIndex; /// Initialized by ShuffleTextBoxes() ... to be used in the future in case of test benches with two lines
RegisterReaders.S640Stream.S640Stream[] optoHeads;
///
/// Parameters and current state of activities
///
DebugMode debugLevel;
int optoDataTimeout;
string fileExchangePath;
int fileExchangeTimeout;
bool enterSerialNumbers;
bool skipBadMeters;
ProcParams pPars;
///
IList<S640Activity> activities;
IList<Test> tests;
///
int currentActivityIx;
///
Step step;
DateTime savedTimestamp;
bool areNewSNsAndRadioAddressesAssigned;
System.Windows.Forms.Timer timer;
///
/// Used in Step.WatchOptoHeads, initially all zeros
///
int[] commOkLoopsCount;
/// <summary>
/// Parameterless constructor (without watermeters, threads)
/// </summary>
public S640CommForm()
{
InitializeComponent();
labels = new Label[UIBoxesCount]
{
wmLabel1, wmLabel2, wmLabel3, wmLabel4, wmLabel5, wmLabel6, wmLabel7, wmLabel8,
wmLabel9, wmLabel10, wmLabel11, wmLabel12, wmLabel13, wmLabel14, wmLabel15, wmLabel16,
wmLabel17, wmLabel18, wmLabel19, wmLabel20, wmLabel21, wmLabel22, wmLabel23, wmLabel24,
wmLabel25, wmLabel26, wmLabel27, wmLabel28, wmLabel29, wmLabel30, wmLabel31, wmLabel32,
wmLabel33, wmLabel34, wmLabel35, wmLabel36, wmLabel37, wmLabel38, wmLabel39, wmLabel40,
};
pictures = new PictureBox[UIBoxesCount]
{
pictureBox1, pictureBox2, pictureBox3, pictureBox4, pictureBox5,
pictureBox6, pictureBox7, pictureBox8, pictureBox9, pictureBox10,
pictureBox11, pictureBox12, pictureBox13, pictureBox14, pictureBox15,
pictureBox16, pictureBox17, pictureBox18, pictureBox19, pictureBox20,
pictureBox21, pictureBox22, pictureBox23, pictureBox24, pictureBox25,
pictureBox26, pictureBox27, pictureBox28, pictureBox29, pictureBox30,
pictureBox31, pictureBox32, pictureBox33, pictureBox34, pictureBox35,
pictureBox36, pictureBox37, pictureBox38, pictureBox39, pictureBox40,
};
messages = new TextBox[UIBoxesCount]
{
fromOptoTextBox1, fromOptoTextBox2, fromOptoTextBox3, fromOptoTextBox4, fromOptoTextBox5,
fromOptoTextBox6, fromOptoTextBox7, fromOptoTextBox8, fromOptoTextBox9, fromOptoTextBox10,
fromOptoTextBox11, fromOptoTextBox12, fromOptoTextBox13, fromOptoTextBox14, fromOptoTextBox15,
fromOptoTextBox16, fromOptoTextBox17, fromOptoTextBox18, fromOptoTextBox19, fromOptoTextBox20,
fromOptoTextBox21, fromOptoTextBox22, fromOptoTextBox23, fromOptoTextBox24, fromOptoTextBox25,
fromOptoTextBox26, fromOptoTextBox27, fromOptoTextBox28, fromOptoTextBox29, fromOptoTextBox30,
fromOptoTextBox31, fromOptoTextBox32, fromOptoTextBox33, fromOptoTextBox34, fromOptoTextBox35,
fromOptoTextBox36, fromOptoTextBox37, fromOptoTextBox38, fromOptoTextBox39, fromOptoTextBox40,
};
serialNumbers = new TextBox[UIBoxesCount]
{
textBox1, textBox2, textBox3, textBox4, textBox5, textBox6, textBox7, textBox8,
textBox9, textBox10, textBox11, textBox12, textBox13, textBox14, textBox15, textBox16,
textBox17, textBox18, textBox19, textBox20, textBox21, textBox22, textBox23, textBox24,
textBox25, textBox26, textBox27, textBox28, textBox29, textBox30, textBox31, textBox32,
textBox33, textBox34, textBox35, textBox36, textBox37, textBox38, textBox39, textBox40,
};
checkBoxes = new CheckBoxImage[UIBoxesCount]
{
checkBoxImage1, checkBoxImage2, checkBoxImage3, checkBoxImage4, checkBoxImage5,
checkBoxImage6, checkBoxImage7, checkBoxImage8, checkBoxImage9, checkBoxImage10,
checkBoxImage11, checkBoxImage12, checkBoxImage13, checkBoxImage14, checkBoxImage15,
checkBoxImage16, checkBoxImage17, checkBoxImage18, checkBoxImage19, checkBoxImage20,
checkBoxImage21, checkBoxImage22, checkBoxImage23, checkBoxImage24, checkBoxImage25,
checkBoxImage26, checkBoxImage27, checkBoxImage28, checkBoxImage29, checkBoxImage30,
checkBoxImage31, checkBoxImage32, checkBoxImage33, checkBoxImage34, checkBoxImage35,
checkBoxImage36, checkBoxImage37, checkBoxImage38, checkBoxImage39, checkBoxImage40,
};
ckbIndex = new int[UIBoxesCount]; /// Initialized by ShuffleTextBoxes() ... to be used in the future in case of test benches with two lines
}
/// <summary>
/// Constructor for one S640Communication test
/// </summary>
/// <param name="waterMetersCount">Number of text boxes for serial numbers</param>
public S640CommForm(S640Activity activity, I640Cfg cfg, Generic.IProcedureParams procParams, Test test)
: this(new List<S640Activity> { activity }, cfg, procParams, new List<Test> { test })
{
}
/// <summary>
/// Constructor for multiple S640Communication tests
/// </summary>
/// <param name="waterMetersCount">Number of text boxes for serial numbers</param>
public S640CommForm(IList<S640Activity> activities, I640Cfg cfg, Generic.IProcedureParams procParams, IList<Test> tests)
: this()
{
this.activities = activities;
debugLevel = cfg.DebugLevel;
optoDataTimeout = cfg.OptoDataTimeout;
fileExchangePath = string.IsNullOrEmpty(cfg.FileExchangePath) ? string.Empty : cfg.FileExchangePath;
fileExchangeTimeout = cfg.FileExchangeTimeout;
enterSerialNumbers = cfg.EnterSerialNumbers;
skipBadMeters = cfg.SkipBadMeters;
this.tests = tests;
this.pPars = procParams as ProcParams;
if (activities.Count != tests.Count)
{
throw new Exception("Something strange: activities.Count != tests.Count");
}
if (ProcessData.RegisterReaders.Length != ProcessData.BatchRslts.Batch.WaterMeters.Count)
{
throw new Exception("Something strange: RegisterReaders.Length != WaterMeters.Count");
}
if (activities.Count > 0)
{
ProcessData.RegisterReaders = StateMachine.GetMetersPath(tests[0]).RegisterReaders;
}
optoHeads = new RegisterReaders.S640Stream.S640Stream[ProcessData.RegisterReaders.Length];
///
for (int wmPos = 0; wmPos < ProcessData.RegisterReaders.Length; wmPos++)
{
optoHeads[wmPos] = ProcessData.RegisterReaders[wmPos] as RegisterReaders.S640Stream.S640Stream;
}
WaterMetersCount = ProcessData.RegisterReaders.Length;
ShuffleTextBoxes(WaterMetersCount, ProcessData.LineSize);
enabledInConfiguration = new bool[textBoxesCount];
for (int i = 0; i < textBoxesCount; i++)
{
enabledInConfiguration[i] = (optoHeads[i] != null) && ((Program.LocalSettings.OptoHeadsEnabled & (1L << i)) != 0L);
}
areNewSNsAndRadioAddressesAssigned = false;
formCompleted = false;
StartForceCloseHandler();
}
/// <summary>
/// Make sure the layout of labels/text boxes on the screen
/// corresponds to the layout of watermeters of the test bench.
/// </summary>
/// <param name="wmsCount">Number of watermeters</param>
/// <param name="lineSize">Number of watermeters in one line</param>
void ShuffleTextBoxes(int wmsCount, int lineSize)
{
textBoxesCount = UIBoxesCount;
///
if (wmsCount < textBoxesCount && lineSize > 0)
{
int nrLines = (wmsCount + lineSize - 1) / lineSize;
int gap = (textBoxesCount - wmsCount) / nrLines;
int dest = 0;
for (int l = 0; l < nrLines; l++)
{
for (int i = 0; i < lineSize; i++)
{
labels[dest] = labels[l * lineSize + l * gap + i];
pictures[dest] = pictures[l * lineSize + l * gap + i];
messages[dest] = messages[l * lineSize + l * gap + i];
serialNumbers[dest] = serialNumbers[l * lineSize + l * gap + i];
checkBoxes[dest] = checkBoxes[l * lineSize + l * gap + i];
ckbIndex[l * lineSize + l * gap + i] = dest;
dest++;
}
}
textBoxesCount = wmsCount;
}
for (int i = 0; i < textBoxesCount; i++)
{
labels[i].Visible = pictures[i].Visible = messages[i].Visible = checkBoxes[i].Visible = true;
if (optoHeads[i] != null) labels[i].Text = (i + 1).ToString();
}
///
/// Resize this form to fit enabled controls
///
//int xMax = 0;
//int yMax = 0;
//for (int i = 0; i < textBoxesCount; i++)
//{
// if (messages[i].Left + messages[i].Width > xMax) xMax = messages[i].Left + messages[i].Width;
// if (messages[i].Top + messages[i].Height > yMax) yMax = messages[i].Top + messages[i].Height;
//}
/////Width = xMax + 30;
//Height = yMax + 50;
}
private void S640CommForm_Load(object sender, EventArgs e)
{
Localize();
///
/// Set location and checkbox states to values stored in local settings
///
TBF.LocalSettings ls = Program.LocalSettings;
Left = (ls.S640CommFormLeft != 0) ? ls.S640CommFormLeft : 150;
Top = (ls.S640CommFormTop != 0) ? ls.S640CommFormTop : 150;
///
/// Set checkbox states accroding to optoHeads[i].Disabled states
///
for (int i = 0; i < textBoxesCount; i++)
{
if (!enabledInConfiguration[i])
{
/// Opto head is disabled in configuration
checkBoxes[i].Checked = false;
checkBoxes[i].Enabled = false;
pictures[i].BackColor = DisabledColor;
messages[i].Text = Strings.Opto_head_is_disabled_in_configuration;
}
else if ((i >= ProcessData.BatchRslts.Batch.WaterMeters.Count) ||
ProcessData.BatchRslts.Batch.WaterMeters[i] == null ||
ProcessData.BatchRslts.Batch.WaterMeters[i].Disabled)
{
/// Opto head was disabled by an operator
checkBoxes[i].Checked = false;
checkBoxes[i].Enabled = false;
pictures[i].BackColor = DisabledColor;
messages[i].Text = Strings.Head_was_disabled_by_the_user;
}
else
{
/// Opto head is enabled
checkBoxes[i].Checked = true;
checkBoxes[i].Enabled = true;
messages[i].Text = "---";
}
/// Reset opto-data indication
pictures[i].BackColor = OptoNokColor;
messages[i].Enabled = true;
if (enterSerialNumbers)
{
serialNumbers[i].Visible = enabledInConfiguration[i];
serialNumbers[i].Enabled = (activities[currentActivityIx] == S640Activity.End);
}
}
startTimeSec = StateMachine.Time;
StartActivity(0);
timer = new System.Windows.Forms.Timer();
timer.Interval = 300; // ms
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
}
void Localize()
{
/// Close/Continue button is localized in other code
Text = Strings.Water_Meter_States;
retryButton.Text = Strings.RetryBtnText;
sampleLabel1.Text = Strings.Optical_head_is_placed_correctly;
sampleLabel2.Text = Strings.Missing_opto_pulses;
samplePictureBox1.BackColor = OptoOKColor;
samplePictureBox2.BackColor = OptoNokColor;
}
void StartActivity(int acIx)
{
startTime = DateTime.Now;
activityLabel.Text = activities[acIx].ToString();
currentActivityIx = acIx;
step = (activities[acIx] == S640Activity.Start) ? Step.WatchOptoHeads : enterSerialNumbers ? Step.EnterSNs : Step.ConfirmSNsAndRadioAddresses;
closeButton.Visible = false;
retryButton.Visible = false;
responseTextBox.Text = string.Empty;
if (step == Step.WatchOptoHeads)
{
/// Start watching optical heads --> reset OK loop counters
if (commOkLoopsCount == null || commOkLoopsCount.Length != textBoxesCount)
{
commOkLoopsCount = new int[textBoxesCount];
}
for (int i = 0; i < textBoxesCount; i++) commOkLoopsCount[i] = 0;
progressBar1.Visible = (optoDataTimeout != 0);
progressBar1.Minimum = 0;
progressBar1.Maximum = Math.Max(optoDataTimeout, 1);
progressBar1.Value = 0;
}
TBF.UiBridge.TestProgressEventArgs.SetEstimatedTimes(new int[] { 0, 0, 10, 0, 140, 0, 0, 0 });
TBF.UiBridge.Bridge.OnTestProgress(null, new TBF.UiBridge.TestProgressEventArgs(tests[acIx], Progress.JustStarted));
sirtDataLogger.InfoFormat(""); /// Makes the log more readable when there is a lot of data
sirtDataLogger.WarnFormat("Activity = {0}", activities[acIx]);
sirtDataLogger.InfoFormat(""); /// Makes the log more readable when there is a lot of data
}
/// <summary>
/// Invoked every 0.5 sec.
/// </summary>
void timer_Tick(object sender, EventArgs args)
{
///--------------------------------------------------------------------------
if (step == Step.WatchOptoHeads)
{
long optoHeadsConfig = Program.LocalSettings.OptoHeadsEnabled;
bool allOK = true;
for (int i = 0; i < textBoxesCount; i++)
{
if ((optoHeadsConfig & (1L << i)) == 0 || optoHeads[i] == null)
{
/// Opto head is disabled in configuration
checkBoxes[i].Checked = false;
checkBoxes[i].Enabled = false;
pictures[i].BackColor = DisabledColor;
messages[i].Text = Strings.Opto_head_is_disabled_in_configuration;
}
else if (!checkBoxes[i].Checked)
{
/// Opto head was disabled by the user
pictures[i].BackColor = DisabledColor;
}
else
{
/// Opto head is enabled
checkBoxes[i].Checked = true;
checkBoxes[i].Enabled = true;
if (optoHeads[i].PcbNumber == 0)
{
/// Communication is NOK right now
pictures[i].BackColor = OptoNokColor;
messages[i].Text = "---";
commOkLoopsCount[i] = 0;
allOK = false;
}
else
{
/// Communication is OK right now
messages[i].Text = string.Format("pcb = {0} radio = {1}", optoHeads[i].PcbNumber, optoHeads[i].RadioAddress);
pictures[i].BackColor = OptoOKColor;
/// increment commOkLoopsCount[i] and check its value, considered OK just after 5 repeats
commOkLoopsCount[i] = commOkLoopsCount[i] + 1;
if (commOkLoopsCount[i] < 5) allOK = false;
}
}
}
if (allOK)
{
log.WarnFormat("allOk");
/// Update water meter properties
for (int i = 0; i < textBoxesCount; i++)
{
if (i < ProcessData.BatchRslts.Batch.WaterMeters.Count &&
ProcessData.BatchRslts.Batch.WaterMeters[i] != null &&
!ProcessData.BatchRslts.Batch.WaterMeters[i].Disabled)
{
if ((optoHeadsConfig & (1L << i)) != 0 && checkBoxes[i].Checked && optoHeads[i] != null)
{
/// Save PCB Number of the water meter
ProcessData.BatchRslts.Batch.WaterMeters[i].SerialNrAux = optoHeads[i].PcbNumber.ToString(); /// PCB number (640)
#if ORACLE_DB
ProcessData.BatchRslts.Batch.WaterMeters[i].OriRadioAddress = /// Original radio address (640)
#endif
ProcessData.BatchRslts.Batch.WaterMeters[i].RadioAddress = optoHeads[i].RadioAddress.ToString(); /// New radio address (640)
}
else
{
/// Disable the water meter
ProcessData.BatchRslts.Batch.WaterMeters[i].Disabled = true;
}
}
checkBoxes[i].Enabled = false;
}
step = Step.SaveStartPro;
}
else if (optoDataTimeout != 0 && DateTime.Now - startTime > new TimeSpan(0, 0, optoDataTimeout))
{
activityLabel.Text = String.Format("{0}: {1} {2}", Strings.Start, Strings.Optical_heads, Strings.Timeout);
log.Error("Start: Optical heads timeout");
step = Step.ConfirmError;
}
else if (optoDataTimeout != 0)
{
progressBar1.Value = (int)Math.Round((DateTime.Now - startTime).TotalSeconds);
}
}
///--------------------------------------------------------------------------
else if (step == Step.SaveStartPro)
{
activityLabel.Text = string.Format("Start: SIRT Communication");
int count = 0;
for (int i = 0; i < textBoxesCount; i++)
{
if (optoHeads[i] != null && optoHeads[i].PcbNumber != 0 && ProcessData.BatchRslts.Batch.WaterMeters[i] != null) count++;
}
log.DebugFormat("Saving '{0}' file: {1} water meters found", StartFileName, count);
if (debugLevel == DebugMode.Normal)
{
SaveProFile(Path.Combine(fileExchangePath, StartFileName), S640Activity.Start, optoHeads);
}
SaveProFile(Path.Combine(Constants.SirtLogDir,
string.Format("{0:yyMMdd-HHmmss}-b{1}-{2}", DateTime.Now, ProcessData.BatchRslts.Batch.BatchNr, StartFileName)),
S640Activity.Start, optoHeads);
savedTimestamp = DateTime.Now;
progressBar1.Visible = (fileExchangeTimeout != 0);
progressBar1.Minimum = 0;
progressBar1.Maximum = Math.Max(fileExchangeTimeout, 1);
progressBar1.Value = 0;
for (int i = 0; i < textBoxesCount; i++) { messages[i].Enabled = false; }
bool focused = false;
if (enterSerialNumbers)
{
for (int i = 0; i < textBoxesCount; i++)
{
if (serialNumbers[i].Visible)
{
serialNumbers[i].Enabled = true;
if (!focused)
{
serialNumbers[i].Focus();
focused = true;
}
}
}
closeButton.Visible = true;
closeButton.Enabled = true;
closeButton.Text = Strings.Continue;
step = Step.EnterSNsAndAwaitResponseToStartPro;
}
else
{
step = Step.AwaitResponseToStartPro;
}
}
///--------------------------------------------------------------------------
else if (step == Step.EnterSNsAndAwaitResponseToStartPro)
{
/// Don't do anything, move to the next step in closeButton_Click(...)
}
///--------------------------------------------------------------------------
else if (step == Step.AwaitResponseToStartPro)
{
if (!File.Exists(Path.Combine(fileExchangePath, StartFileName)))
{
/// File disappeared in time
UpdateFirstTestResult(tests);
UiBridge.Bridge.OnTestProgress(null, new TBF.UiBridge.TestProgressEventArgs(tests[currentActivityIx], Progress.Completed));
step = Step.Idle;
NormalClose();
}
else if (File.Exists(Path.Combine(fileExchangePath, ErrorFileName)))
{
/// Error file detected
string destination = Path.Combine(Constants.SirtLogDir,
string.Format("{0:yyMMdd-HHmmss}-b{1}-{2}", DateTime.Now, ProcessData.BatchRslts.Batch.BatchNr, ErrorFileName));
File.Move(Path.Combine(fileExchangePath, ErrorFileName), destination);
ParseFileAndDisplayErrors(destination);
File.Delete(Path.Combine(fileExchangePath, StartFileName));
activityLabel.Text = String.Format("{0}: SIRT {1}", Strings.Start, Strings.Error);
step = Step.ConfirmError;
}
else if (fileExchangeTimeout != 0 && DateTime.Now - savedTimestamp > new TimeSpan(0, 0, fileExchangeTimeout))
{
activityLabel.Text = String.Format("{0}: SIRT {1}", Strings.Start, Strings.Timeout);
log.Error("Start: SIRT timeout");
step = Step.ConfirmError;
}
else if (fileExchangeTimeout != 0)
{
progressBar1.Value = (int)Math.Round((DateTime.Now - savedTimestamp).TotalSeconds);
}
else
{
progressBar1.Visible = false;
closeButton.Text = Strings.CloseBtnText;
closeButton.Visible = true;
retryButton.Visible = true;
}
}
///--------------------------------------------------------------------------
else if (step == Step.EnterSNs)
{
/// Don't do anything, move to the next step in closeButton_Click(...)
}
///--------------------------------------------------------------------------
else if (step == Step.ConfirmSNsAndRadioAddresses)
{
if (!areNewSNsAndRadioAddressesAssigned)
{
AssignNewSNsAndRadioAddresses(optoHeads);
closeButton.Visible = true;
closeButton.Text = Strings.Continue;
}
}
///--------------------------------------------------------------------------
else if (step == Step.SaveEndePro)
{
activityLabel.Text = string.Format("End: SIRT Communication");
log.DebugFormat("Saving '{0}' file", EndFileName);
if (debugLevel == DebugMode.Normal)
{
SaveProFile(Path.Combine(fileExchangePath, EndFileName), S640Activity.End, optoHeads);
}
SaveProFile(Path.Combine(Constants.SirtLogDir,
string.Format("{0:yyMMdd-HHmmss}-b{1}-{2}", DateTime.Now, ProcessData.BatchRslts.Batch.BatchNr, EndFileName)),
S640Activity.Start, optoHeads);
savedTimestamp = DateTime.Now;
progressBar1.Visible = (fileExchangeTimeout != 0);
progressBar1.Minimum = 0;
progressBar1.Maximum = Math.Max(fileExchangeTimeout, 1);
progressBar1.Value = 0;
if (ProcessData.OracleDB != null && ProcessData.OrderDetails != null)
{
int updatedCount = ProcessData.OracleDB.UpdateOrderDetails(ProcessData.OrderDetails);
}
step = Step.AwaitResponseToEndePro;
}
///--------------------------------------------------------------------------
else if (step == Step.AwaitResponseToEndePro)
{
if (!File.Exists(Path.Combine(fileExchangePath, EndFileName)))
{
/// File disappeared in time
UpdateFirstTestResult(tests);
UiBridge.Bridge.OnTestProgress(null, new TBF.UiBridge.TestProgressEventArgs(tests[currentActivityIx], Progress.Completed));
step = Step.Idle;
NormalClose();
}
else if (File.Exists(Path.Combine(fileExchangePath, ErrorFileName)))
{
/// Error.dat file detected
string destination = Path.Combine(Constants.SirtLogDir,
string.Format("{0:yyMMdd-HHmmss}-b{1}-{2}", DateTime.Now, ProcessData.BatchRslts.Batch.BatchNr, ErrorFileName));
File.Move(Path.Combine(fileExchangePath, ErrorFileName), destination);
ParseFileAndDisplayErrors(destination);
File.Delete(Path.Combine(fileExchangePath, EndFileName));
activityLabel.Text = String.Format("{0}: SIRT {1}", Strings.End, Strings.Error);
step = Step.ConfirmError;
}
else if (fileExchangeTimeout != 0 && DateTime.Now - savedTimestamp > new TimeSpan(0, 0, fileExchangeTimeout))
{
activityLabel.Text = String.Format("{0}: SIRT {1}", Strings.End, Strings.Timeout);
log.Error("End: SIRT timeout");
step = Step.ConfirmError;
}
else if (fileExchangeTimeout != 0)
{
progressBar1.Value = (int)Math.Round((DateTime.Now - savedTimestamp).TotalSeconds);
}
else
{
progressBar1.Visible = false;
closeButton.Text = Strings.CloseBtnText;
closeButton.Visible = true;
retryButton.Visible = true;
}
}
///--------------------------------------------------------------------------
else if (step == Step.ConfirmError)
{
progressBar1.Visible = false;
retryButton.Visible = true;
closeButton.Visible = true;
closeButton.Enabled = true;
closeButton.Text = Strings.CloseBtnText;
}
///--------------------------------------------------------------------------
else if (step == Step.Idle)
{
/// Just wait until this form is closed
}
else
{
/// Invalid step
log.ErrorFormat("Unexpected step: activity = {0} step = {1}", activities[currentActivityIx], step);
}
}
bool AssignNewSNsAndRadioAddresses(RegisterReaders.S640Stream.S640Stream[] optoHeads)
{
TBF.Rig.Output.DB.SensusOracle.OrderDetails ord = ProcessData.OrderDetails;
///
if (ProcessData.OracleDB == null || ord == null || !ProcessData.OracleDB.ReadOrderDetails(ref ord))
{
return false;
}
if (ord.CurrentSerialNr < ord.FirstSerialNr)
{
ord.CurrentSerialNr = ord.FirstSerialNr - 1;
}
for (int i = 0; i < optoHeads.Length; i++)
{
int currentSerialNr = (ord.CurrentSerialNr < ord.FirstSerialNr)
? ord.FirstSerialNr
: ord.CurrentSerialNr + 1;
int currentRadioAddress = (ord.CurrentRadioAddress < ord.FirstRadioAddress)
? ord.FirstRadioAddress
: ord.CurrentSerialNr + 1;
Results.Entities.WaterMeter wm = ProcessData.BatchRslts.Batch.WaterMeters[i];
if (optoHeads[i] != null && optoHeads[i].PcbNumber != 0 && wm != null && !wm.Disabled)
{
if (!wm.PassedFromTests())
{
/// Red background
messages[i].BackColor = Color.Pink;
}
else if (ord.CurrentPcsCount >= ord.TargetPcsCount)
{
/// Disable the water meter to prevent sealing
wm.Disabled = true;
}
else
{
/// Assign numbers
wm.RadioAddress = string.Format("{0}{1}{2}", ord.RadioAddressPrefix, currentRadioAddress.ToString("D9"), ord.RadioAddressSuffix);
#if ORACLE_DB
wm.AssignedSerialNr = currentSerialNr;
string assingedSNStr = currentSerialNr.ToString(string.Format("D{0}", ord.SNLength));
wm.Prefix = ord.Prefix;
wm.Suffix = ord.Suffix;
wm.CompleteSerialNr = string.Format("{0}{1}{2}", wm.Prefix, assingedSNStr, wm.Suffix);
messages[i].Text = string.Format("s/n = {0} radio = {1}", assingedSNStr, wm.RadioAddress);
#endif
ord.CurrentSerialNr = currentSerialNr;
ord.CurrentRadioAddress = currentRadioAddress;
ord.CurrentPcsCount++;
}
}
}
areNewSNsAndRadioAddressesAssigned = true;
return true;
}
void SaveProFile(string filename, S640Activity activity, RegisterReaders.S640Stream.S640Stream[] optoHeads)
{
/// Variant: 1.from OrderDetails, 2.from Procedure.WatermetersStr, 3.empty
string variant = (ProcessData.OrderDetails != null && !string.IsNullOrEmpty(ProcessData.OrderDetails.VariantenCode))
? ProcessData.OrderDetails.VariantenCode /// 1
: !string.IsNullOrEmpty(ProcessData.BatchRslts.Batch.WatermetersStr)
? ProcessData.BatchRslts.Batch.WatermetersStr /// 2
: string.Empty; /// 3
/// Module parameter
string moduleParam = (pPars.ModuleParameter.ToLower().Contains("vt_auftrag_pd") && ProcessData.OrderDetails != null)
? ProcessData.OrderDetails.ModuleParameter
: pPars.ModuleParameter;
/// Purchase order and water meters count
int count = 0;
string purchaseOrder = null;
for (int i = 0; i < optoHeads.Length; i++)
{
if (optoHeads[i] != null &&
optoHeads[i].PcbNumber != 0 &&
ProcessData.BatchRslts.Batch.WaterMeters[i] != null &&
!ProcessData.BatchRslts.Batch.WaterMeters[i].Disabled &&
(activity == S640Activity.Start || ProcessData.BatchRslts.Batch.WaterMeters[i].PassedFromTests()))
{
count++;
if (purchaseOrder == null && !string.IsNullOrEmpty(ProcessData.BatchRslts.Batch.WaterMeters[i].PurchaseOrder))
{
purchaseOrder = ProcessData.BatchRslts.Batch.WaterMeters[i].PurchaseOrder;
}
}
}
if (ProcessData.OrderDetails != null)
{
purchaseOrder = ProcessData.OrderDetails.AuftragsNummer;
}
using (StreamWriter file = new StreamWriter(filename))
{
file.WriteLine("<?xml version=\"1.0\" ?>");
file.WriteLine("<Batch xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">");
file.WriteLine(string.Format(" <TimeStamp>{0}</TimeStamp>", DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss.fffzzz")));
file.WriteLine(string.Format(" <Bench Mode=\"{0}\" Count=\"{1}\" TestBenchID=\"{2}\" TestBenchName=\"{3}\" EncyptionKeyMode=\"{4}\" />",
(activity == S640Activity.Start) ? "Start" : "End",
count,
ProcessData.BenchInfo.TestBenchId,
ProcessData.BenchInfo.TestBenchName,
"SensusKey"));
file.WriteLine(string.Format(" <OrderData Variantencode=\"{0}\" OrderNo=\"{1}\" ModulParameter=\"{2}\" />",
variant, (purchaseOrder != null) ? purchaseOrder : string.Empty, moduleParam));
file.WriteLine(" <Meters>");
for (int i = 0; i < optoHeads.Length; i++)
{
if (optoHeads[i] != null &&
optoHeads[i].PcbNumber != 0 &&
ProcessData.BatchRslts.Batch.WaterMeters[i] != null &&
!ProcessData.BatchRslts.Batch.WaterMeters[i].Disabled &&
(activity == S640Activity.Start || ProcessData.BatchRslts.Batch.WaterMeters[i].PassedFromTests()))
{
Results.Entities.WaterMeter wm = ProcessData.BatchRslts.Batch.WaterMeters[i];
if (activity == S640Activity.Start)
{
file.WriteLine(string.Format(" <Meter RadioAddress=\"{0}\" MeterNumber=\"{0}\" CustomerText=\"\" NewRadioAddress=\"{0}\" PCBNumber=\"{1}\" EncyptionKey=\"\" />",
wm.RadioAddress,
wm.SerialNrAux));
}
else if (activity == S640Activity.End)
{
#if ORACLE_DB
file.WriteLine(string.Format(" <Meter RadioAddress=\"{0}\" MeterNumber=\"{1}\" CustomerText=\"{2}\" NewRadioAddress=\"{3}\" PCBNumber=\"{4}\" EncyptionKey=\"\" />",
wm.OriRadioAddress,
wm.AssignedSerialNr.ToString(),
wm.AssignedSerialNr.ToString(),
wm.RadioAddress,
wm.SerialNrAux));
#endif
}
}
}
file.WriteLine(" </Meters>");
file.WriteLine(string.Format(" <Metro Enable=\"{0}\" PulseRatePiston=\"{1}\" PulseRateLED=\"{2}\" OffsetFactor=\"{3}\" FactoryCalibration=\"{4}\" Units=\"{5}\" MeterSize=\"{6}\" OffsetTime=\"{7}\" />",
B2S(pPars.MetroEnable),
pPars.PulseRatePiston.ToString("F3", CultureInfo.InvariantCulture),
pPars.PulseRateLed.ToString(CultureInfo.InvariantCulture),
pPars.OffsetFactor.ToString(CultureInfo.InvariantCulture),
pPars.FactoryCalibration,
pPars.Units,
pPars.MeterSize,
pPars.OffsetTime));
file.WriteLine(string.Format(" <NewRead Enable=\"{0}\" NewRead=\"{1}\" />", B2S(pPars.NewReadEnable), pPars.NewRead));
file.WriteLine(string.Format(" <TransInterval Enable=\"{0}\" Interval=\"{1}\" />", B2S(pPars.TransIntervalEnable), pPars.TransInterval));
file.WriteLine(string.Format(" <LatInterval Enable=\"{0}\" Interval=\"{1}\" />", B2S(pPars.LatIntervalEnable), pPars.LatInterval));
file.WriteLine(string.Format(" <ResetAlarm Enable=\"{0}\" />", B2S(pPars.ResetAlarmEnable)));
file.WriteLine(string.Format(" <MetrologyTestMode Enable=\"{0}\" Hours=\"{1}\" />", B2S(pPars.MetrologyTestModeEnable), pPars.MetrologyTestModeHours));
file.WriteLine(string.Format(" <OpticalTeleg Enable=\"{0}\" Minutes=\"{1}\" />", B2S(pPars.OpticalTelegramEnable), pPars.OpticalTelegramMinutes));
file.WriteLine(string.Format(" <ChangeRadio Enable=\"{0}\" />", B2S(pPars.ChangeRadioEnable)));
file.WriteLine(string.Format(" <ChangeMeterID Enable=\"{0}\" />", B2S(pPars.ChangeMeterIDEnable)));
file.WriteLine(string.Format(" <SoftSeal Enable=\"{0}\" />", B2S(pPars.SoftSealEnable)));
file.WriteLine(string.Format(" <GoToSleep Enable=\"{0}\" />", B2S(pPars.GoToSleepEnable)));
file.WriteLine(string.Format(" <SaveDB Enable=\"{0}\" />", B2S(pPars.SaveDBEnable)));
file.WriteLine("</Batch>");
}
}
/// <summary>
/// Boolean to lowercase string
/// </summary>
string B2S(bool b)
{
return b ? "true" : "false";
}
void ParseFileAndDisplayErrors(string fileName)
{
log.ErrorFormat("ParseFileAndDisplayErrors(\"{0}\")", fileName);
string message = File.ReadAllText(fileName);
responseTextBox.Text = message;
}
/// <summary>
/// Update test result representing RFID communication success/failure
/// </summary>
/// <param name="test"></param>
void UpdateFirstTestResult(IList<Config.Entities.Test> tests, bool commFailed = false)
{
DateTime endTime = DateTime.Now;
int testTime = StateMachine.Time - startTimeSec;
if (!tests.Contains(StateMachine.TestInstances[0].Test))
{
tests.Insert(0, StateMachine.TestInstances[0].Test); /// Add RFID test as the 1st item
}
foreach (var test in tests)
{
Results.Entities.TestRslt tstRslt = ProcessData.BatchRslts.GetTestRslt(test.Name, test.Part);
if (tstRslt != null)
{
Results.Utils.GetCounterStates(tstRslt, Program.LocalSettings.Counters);
/// Auxiliary results ... not required
/// Main results
tstRslt.MethodClass = TbfComponents.FindComponent(test.Method).ClassName;
tstRslt.TestDone = true;
tstRslt.StartTime = tstRslt.Batch.StartTime;
tstRslt.EndTime = endTime;
tstRslt.FlowSetTime = 0;
tstRslt.MassOfEvapWater = 0;
tstRslt.TestTime += testTime; /// [s] total communication time of all tests
for (int i = 0; i < textBoxesCount; i++)
{
Results.Entities.MeterTestRslt meterRslt =
ProcessData.BatchRslts.GetMeterTestRslt(test.Name, i, Common.CompoundMeterId.Single);
if (meterRslt != null && (i < ProcessData.BatchRslts.Batch.WaterMeters.Count) &&
ProcessData.BatchRslts.Batch.WaterMeters[i] != null &&
!ProcessData.BatchRslts.Batch.WaterMeters[i].Disabled)
{
if (enabledInConfiguration[i] && !commFailed)
{
meterRslt.TestDone = true;
meterRslt.Passed = true;
}
else
{
meterRslt.TestDone = true;
meterRslt.Passed = false;
}
}
}
}
}
}
private void closeButton_Click(object sender, EventArgs e)
{
if (step == Step.EnterSNsAndAwaitResponseToStartPro)
{
UpdateSerialNumbers();
step = Step.AwaitResponseToEndePro;
closeButton.Visible = false;
}
else if (step == Step.EnterSNs)
{
UpdateSerialNumbers();
step = Step.ConfirmSNsAndRadioAddresses;
closeButton.Visible = false;
}
else if (step == Step.ConfirmSNsAndRadioAddresses)
{
step = Step.SaveEndePro;
closeButton.Visible = false;
}
else
{
log.Error("User is closing this form, communication failed");
UpdateFirstTestResult(tests, true);
UiBridge.Bridge.OnTestProgress(null, new TBF.UiBridge.TestProgressEventArgs(tests[currentActivityIx], Progress.Aborted));
NormalClose();
}
}
private void UpdateSerialNumbers()
{
/// Update water meter properties
for (int i = 0; i < textBoxesCount; i++)
{
if (i < ProcessData.BatchRslts.Batch.WaterMeters.Count &&
ProcessData.BatchRslts.Batch.WaterMeters[i] != null &&
!ProcessData.BatchRslts.Batch.WaterMeters[i].Disabled &&
serialNumbers[i].Visible)
{
/// Save brass water meter body serial number
ProcessData.BatchRslts.Batch.WaterMeters[i].SerialNr = serialNumbers[i].Text;
serialNumbers[i].Enabled = false;
}
}
}
private void NormalClose()
{
if (Program.LocalSettings.S640CommFormLeft != Location.X ||
Program.LocalSettings.S640CommFormTop != Location.Y)
{
/// Update local settings
Program.LocalSettings.S640CommFormLeft = Location.X;
Program.LocalSettings.S640CommFormTop = Location.Y;
Program.LocalSettings.Save();
}
formCompleted = true;
DialogResult = DialogResult.OK;
Close();
}
#region Forced close handling
public void StartForceCloseHandler()
{
UiBridge.Bridge.CloseModelessFormHandler += delegate(object sender, EventArgs args)
{
if (InvokeRequired) { Invoke(new EventHandler<EventArgs>(OnForceClose), sender, args); }
else OnForceClose(sender, args);
};
}
void OnForceClose(object sender, EventArgs args)
{
forcedClose = true;
DialogResult = DialogResult.Cancel;
Close();
}
#endregion
private void S640CommForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (!forcedClose && !formCompleted)
{
e.Cancel = true;
}
}
private void retryButton_Click(object sender, EventArgs e)
{
if (step == Step.ConfirmError)
{
StartActivity(0);
}
}
private void textBox1_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox1); }
private void textBox2_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox2); }
private void textBox3_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox3); }
private void textBox4_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox4); }
private void textBox5_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox5); }
private void textBox6_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox6); }
private void textBox7_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox7); }
private void textBox8_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox8); }
private void textBox9_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox9); }
private void textBox10_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox10); }
private void textBox11_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox11); }
private void textBox12_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox12); }
private void textBox13_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox13); }
private void textBox14_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox14); }
private void textBox15_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox15); }
private void textBox16_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox16); }
private void textBox17_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox17); }
private void textBox18_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox18); }
private void textBox19_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox19); }
private void textBox20_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox20); }
private void textBox21_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox21); }
private void textBox22_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox22); }
private void textBox23_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox23); }
private void textBox24_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox24); }
private void textBox25_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox25); }
private void textBox26_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox26); }
private void textBox27_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox27); }
private void textBox28_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox28); }
private void textBox29_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox29); }
private void textBox30_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox30); }
private void textBox31_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox31); }
private void textBox32_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox32); }
private void textBox33_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox33); }
private void textBox34_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox34); }
private void textBox35_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox35); }
private void textBox36_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox36); }
private void textBox37_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox37); }
private void textBox38_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox38); }
private void textBox39_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox39); }
private void textBox40_KeyPress(object sndr, KeyPressEventArgs e) { ProcKeyPress(sndr, e, textBox40); }
/// <summary>
/// Process a key press within any enabled text boxe
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
/// <param name="currentFocusOwner">TextBox control which received the event</param>
private void ProcKeyPress(object sender, KeyPressEventArgs e, TextBox currentFocusOwner)
{
if (e.KeyChar == '\r')
{
/// Process <enter> key ..... Next text field
if (textBoxesCount < 2) return; /// There is just one enabled textBox
for (int i = 0; i < textBoxesCount; i++)
{
if (serialNumbers[i] == currentFocusOwner)
{
int nextIx = i;
do
{
nextIx = (++nextIx) % textBoxesCount;
}
while (!serialNumbers[nextIx].Visible);
/// Change focus to the next enabled text box
serialNumbers[nextIx].Focus();
return;
}
}
}
}
private void checkBoxImage1_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage1, fromOptoTextBox1, textBox1); }
private void checkBoxImage2_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage2, fromOptoTextBox2, textBox2); }
private void checkBoxImage3_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage3, fromOptoTextBox3, textBox3); }
private void checkBoxImage4_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage4, fromOptoTextBox4, textBox4); }
private void checkBoxImage5_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage5, fromOptoTextBox5, textBox5); }
private void checkBoxImage6_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage6, fromOptoTextBox6, textBox6); }
private void checkBoxImage7_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage7, fromOptoTextBox7, textBox7); }
private void checkBoxImage8_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage8, fromOptoTextBox8, textBox8); }
private void checkBoxImage9_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage9, fromOptoTextBox9, textBox9); }
private void checkBoxImage10_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage10, fromOptoTextBox10, textBox10); }
private void checkBoxImage11_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage11, fromOptoTextBox11, textBox11); }
private void checkBoxImage12_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage12, fromOptoTextBox12, textBox12); }
private void checkBoxImage13_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage13, fromOptoTextBox13, textBox13); }
private void checkBoxImage14_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage14, fromOptoTextBox14, textBox14); }
private void checkBoxImage15_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage15, fromOptoTextBox15, textBox15); }
private void checkBoxImage16_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage16, fromOptoTextBox16, textBox16); }
private void checkBoxImage17_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage17, fromOptoTextBox17, textBox17); }
private void checkBoxImage18_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage18, fromOptoTextBox18, textBox18); }
private void checkBoxImage19_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage19, fromOptoTextBox19, textBox19); }
private void checkBoxImage20_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage20, fromOptoTextBox20, textBox20); }
private void checkBoxImage21_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage21, fromOptoTextBox21, textBox21); }
private void checkBoxImage22_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage22, fromOptoTextBox22, textBox22); }
private void checkBoxImage23_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage23, fromOptoTextBox23, textBox23); }
private void checkBoxImage24_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage24, fromOptoTextBox24, textBox24); }
private void checkBoxImage25_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage25, fromOptoTextBox25, textBox25); }
private void checkBoxImage26_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage26, fromOptoTextBox26, textBox26); }
private void checkBoxImage27_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage27, fromOptoTextBox27, textBox27); }
private void checkBoxImage28_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage28, fromOptoTextBox28, textBox28); }
private void checkBoxImage29_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage29, fromOptoTextBox29, textBox29); }
private void checkBoxImage30_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage30, fromOptoTextBox30, textBox30); }
private void checkBoxImage31_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage31, fromOptoTextBox31, textBox31); }
private void checkBoxImage32_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage32, fromOptoTextBox32, textBox32); }
private void checkBoxImage33_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage33, fromOptoTextBox33, textBox33); }
private void checkBoxImage34_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage34, fromOptoTextBox34, textBox34); }
private void checkBoxImage35_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage35, fromOptoTextBox35, textBox35); }
private void checkBoxImage36_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage36, fromOptoTextBox36, textBox36); }
private void checkBoxImage37_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage37, fromOptoTextBox37, textBox37); }
private void checkBoxImage38_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage38, fromOptoTextBox38, textBox38); }
private void checkBoxImage39_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage39, fromOptoTextBox39, textBox39); }
private void checkBoxImage40_Click(object sender, EventArgs e) { ProcessClick(checkBoxImage40, fromOptoTextBox40, textBox40); }
void ProcessClick(CheckBoxImage checkBox, TextBox messageBox, TextBox snTextBox)
{
messageBox.Text = checkBox.Checked ? string.Empty : Strings.Head_was_disabled_by_the_user;
if (skipBadMeters)
{
snTextBox.Visible = checkBox.Checked;
}
}
}
}