Workplace...S640Stream : New evaluation, Green/yellow progress bar, Interval 400ms, ver. 3.1.19
This commit is contained in:
parent
5b9156d670
commit
b4f41a2f1f
28
Workplace/CheckItems/MyProgressBar.cs
Normal file
28
Workplace/CheckItems/MyProgressBar.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using System.Drawing;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace Workplace.CheckItems
|
||||
{
|
||||
public class MyProgressBar : ProgressBar
|
||||
{
|
||||
public int ColorId = 0;
|
||||
|
||||
public MyProgressBar()
|
||||
{
|
||||
this.SetStyle(ControlStyles.UserPaint, true);
|
||||
}
|
||||
|
||||
protected override void OnPaint(PaintEventArgs e)
|
||||
{
|
||||
Rectangle rec = e.ClipRectangle;
|
||||
|
||||
rec.Width = (int)(rec.Width * ((double)Value / Maximum)) - 4;
|
||||
if(ProgressBarRenderer.IsSupported)
|
||||
ProgressBarRenderer.DrawHorizontalBar(e.Graphics, e.ClipRectangle);
|
||||
rec.Height = rec.Height - 4;
|
||||
|
||||
Brush brush = (ColorId == 1) ? Brushes.Yellow : (ColorId == 2) ? Brushes.Red : Brushes.Green;
|
||||
e.Graphics.FillRectangle(brush, 2, 2, rec.Width, rec.Height);
|
||||
}
|
||||
}
|
||||
}
|
||||
10
Workplace/CheckItems/S640Stream.Designer.cs
generated
10
Workplace/CheckItems/S640Stream.Designer.cs
generated
@ -35,6 +35,7 @@
|
||||
this.descriptionMaterialuLabel = new System.Windows.Forms.Label();
|
||||
this.pcbNumberTextBox = new System.Windows.Forms.TextBox();
|
||||
this.pcbNumberLabel = new System.Windows.Forms.Label();
|
||||
this.pcbNumberProgressBar = new MyProgressBar();
|
||||
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
@ -95,10 +96,18 @@
|
||||
this.pcbNumberLabel.TabIndex = 8;
|
||||
this.pcbNumberLabel.Text = "PCB Number";
|
||||
//
|
||||
// pcbNumberProgressBar
|
||||
//
|
||||
this.pcbNumberProgressBar.Location = new System.Drawing.Point(241, 65);
|
||||
this.pcbNumberProgressBar.Name = "pcbNumberProgressBar";
|
||||
this.pcbNumberProgressBar.Size = new System.Drawing.Size(227, 19);
|
||||
this.pcbNumberProgressBar.TabIndex = 9;
|
||||
//
|
||||
// S640Stream
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(11F, 24F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.Controls.Add(this.pcbNumberProgressBar);
|
||||
this.Controls.Add(this.pcbNumberLabel);
|
||||
this.Controls.Add(this.pcbNumberTextBox);
|
||||
this.Controls.Add(this.descriptionMaterialuLabel);
|
||||
@ -123,5 +132,6 @@
|
||||
private System.Windows.Forms.Label descriptionMaterialuLabel;
|
||||
private System.Windows.Forms.TextBox pcbNumberTextBox;
|
||||
private System.Windows.Forms.Label pcbNumberLabel;
|
||||
private MyProgressBar pcbNumberProgressBar;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,19 +1,23 @@
|
||||
///
|
||||
/// Copyright (c) 2020 Sensus Slovensko a.s.
|
||||
/// Copyright (c) 2020-2023 Sensus Slovensko a.s.
|
||||
///
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.IO.Ports;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using log4net;
|
||||
using SharedDatabase.Entities;
|
||||
using System.Drawing;
|
||||
|
||||
namespace Workplace.CheckItems
|
||||
{
|
||||
public partial class S640Stream : UserControl, IDevice, ICheckItem
|
||||
{
|
||||
const Int64 MaxDropoutTime = 500; /// ms
|
||||
const Int64 MinHoldTime = 2500; /// ms
|
||||
const Int64 MinBreakTime = 10000; /// ms
|
||||
|
||||
|
||||
private static readonly ILog log = LogManager.GetLogger(typeof(S640Stream));
|
||||
|
||||
public override string ToString()
|
||||
@ -21,6 +25,7 @@ namespace Workplace.CheckItems
|
||||
return string.Format("S640Stream: {0} {1}", IxPolozky, Part.Name);
|
||||
}
|
||||
|
||||
|
||||
///
|
||||
/// Check item related variables
|
||||
///
|
||||
@ -44,29 +49,36 @@ namespace Workplace.CheckItems
|
||||
///
|
||||
SerialPort serialPort; /// Used in DebugMode.Normal
|
||||
|
||||
const int FramesBufferSize = 32; /// 8 sec @ 4 Hz
|
||||
S640.DatastreamFrame[] optoData;
|
||||
int optoDataIx;
|
||||
string partOfTelegram; /// Data unprocessed by ReadDatastream(...), contains incomplete frame
|
||||
|
||||
Int64 currentRawVolumeUnwrapped;
|
||||
Int64 currentRawTimeUnwrapped;
|
||||
|
||||
S640.DatastreamFrame frame = new S640.DatastreamFrame();
|
||||
char[] pcbNrStr = new char[12];
|
||||
char[] radioAddrStr = new char[10];
|
||||
///
|
||||
Int64 validPcbNumber;
|
||||
Int64 validRadioAddress;
|
||||
Int64 firstValidTime;
|
||||
Int64 lastValidTime;
|
||||
///
|
||||
Int64 currentPcbNr;
|
||||
Int64 currentRadioAddr;
|
||||
|
||||
///
|
||||
/// PCB Number and Radio address from data stream
|
||||
///
|
||||
public Int64 PcbNumber;
|
||||
public Int64 RadioAddress;
|
||||
///
|
||||
IList<S640.PcbnrRadioaddrWeight> prwList;
|
||||
Int64 lastPcbNumber;
|
||||
Int64 lastNonzeroPcbNumber;
|
||||
Int64 lastSentNonzeroPcbNumber;
|
||||
|
||||
|
||||
S640Stream()
|
||||
{
|
||||
InitializeComponent();
|
||||
BlackListedCodes = new List<string>();
|
||||
prwList = new List<S640.PcbnrRadioaddrWeight>();
|
||||
}
|
||||
|
||||
/// <summary> Empty implementation, might be overriden in derived classes </summary>
|
||||
@ -90,18 +102,16 @@ namespace Workplace.CheckItems
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
partOfTelegram = string.Empty;
|
||||
currentRawVolumeUnwrapped = 0;
|
||||
currentRawTimeUnwrapped = 0;
|
||||
validPcbNumber = (long)-1;
|
||||
validRadioAddress = (long)-1;
|
||||
firstValidTime = 0;
|
||||
lastValidTime = 0;
|
||||
|
||||
partOfTelegram = string.Empty;
|
||||
|
||||
/// Allocate memory for opto-data from iPerl
|
||||
optoData = new S640.DatastreamFrame[FramesBufferSize];
|
||||
for (int i = 0; i < FramesBufferSize; i++)
|
||||
{
|
||||
optoData[i] = new S640.DatastreamFrame { DateTime = DateTime.MinValue };
|
||||
}
|
||||
optoDataIx = 0;
|
||||
sendPcbNr = false;
|
||||
lastSentNonzeroPcbNumber = (long)-1;
|
||||
|
||||
/// Prepare serial port
|
||||
string comPortName = string.Format("COM{0}", Program.LocalSettings.ScaleSerialPort);
|
||||
@ -112,64 +122,84 @@ namespace Workplace.CheckItems
|
||||
log.FatalFormat("{0} initialized: {1}", Name, this);
|
||||
}
|
||||
|
||||
|
||||
public void ClearCode() { }
|
||||
|
||||
public void SubmitCode(string code) { }
|
||||
|
||||
bool hasFocus;
|
||||
bool sendLastPcbNr;
|
||||
bool sendPcbNr;
|
||||
private void setFocusButton_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (!hasFocus && !sendLastPcbNr && PcbNumber != 0 && PcbNumber != lastNonzeroPcbNumber)
|
||||
setFocusButton.Text = ">";
|
||||
|
||||
if (!hasFocus && !sendPcbNr && PcbNumber != 0 && PcbNumber != lastSentNonzeroPcbNumber)
|
||||
{
|
||||
lastNonzeroPcbNumber = PcbNumber;
|
||||
sendLastPcbNr = true;
|
||||
sendPcbNr = true;
|
||||
}
|
||||
|
||||
hasFocus = true;
|
||||
setFocusButton.Text = ">";
|
||||
parent.OnFocusPressed(this, new FocusPressedEventArgs(IxPolozky, Part.CodeLocation));
|
||||
parent.OnFocusPressed(this, new FocusPressedEventArgs(IxPolozky, Part.CodeLocation));
|
||||
}
|
||||
public void ResetFocus()
|
||||
{
|
||||
hasFocus = false;
|
||||
setFocusButton.Text = "";
|
||||
hasFocus = false;
|
||||
}
|
||||
public void SetFocus()
|
||||
{
|
||||
if (!hasFocus && !sendLastPcbNr && PcbNumber != 0 && PcbNumber != lastNonzeroPcbNumber)
|
||||
setFocusButton.Text = ">";
|
||||
|
||||
if (!hasFocus && !sendPcbNr && PcbNumber != 0 && PcbNumber != lastSentNonzeroPcbNumber)
|
||||
{
|
||||
lastNonzeroPcbNumber = PcbNumber;
|
||||
sendLastPcbNr = true;
|
||||
sendPcbNr = true;
|
||||
}
|
||||
|
||||
hasFocus = true;
|
||||
setFocusButton.Text = ">";
|
||||
}
|
||||
|
||||
public void RunDeviceBefore()
|
||||
{
|
||||
lastPcbNumber = PcbNumber;
|
||||
ReadDatastream();
|
||||
ProcessBuffer_UpdatePcbNrAndRA();
|
||||
pcbNumberTextBox.Text = (PcbNumber != 0) ? PcbNumber.ToString() : string.Empty; /// Always displayed
|
||||
|
||||
//if (sendLastPcbNr)
|
||||
//{
|
||||
// sendLastPcbNr = false;
|
||||
// parent.OnBarcodeReceived(this, new BarcodeReceivedEventArgs(lastNonzeroPcbNumber.ToString(), IxPolozky,
|
||||
// Part.CodeLocation, PartError.None));
|
||||
//}
|
||||
//
|
||||
//if (hasFocus && PcbNumber != 0 && PcbNumber != lastNonzeroPcbNumber)
|
||||
|
||||
if (PcbNumber != 0 && PcbNumber != lastNonzeroPcbNumber)
|
||||
/// Send if required
|
||||
if (sendPcbNr)
|
||||
{
|
||||
lastNonzeroPcbNumber = PcbNumber;
|
||||
parent.OnBarcodeReceived(this, new BarcodeReceivedEventArgs(PcbNumber.ToString(), IxPolozky,
|
||||
Part.CodeLocation, PartError.None));
|
||||
lastSentNonzeroPcbNumber = PcbNumber;
|
||||
sendPcbNr = false;
|
||||
if (PcbNumber > 0)
|
||||
{
|
||||
parent.OnBarcodeReceived(this,
|
||||
new BarcodeReceivedEventArgs(PcbNumber.ToString(), IxPolozky, Part.CodeLocation, PartError.None));
|
||||
}
|
||||
}
|
||||
|
||||
ReadDatastream();
|
||||
|
||||
if (hasFocus && PcbNumber != 0 && PcbNumber != lastSentNonzeroPcbNumber)
|
||||
{
|
||||
/// This control owned focus and the PcbNumber became valid
|
||||
sendPcbNr = true;
|
||||
}
|
||||
|
||||
/// Send if required
|
||||
if (sendPcbNr)
|
||||
{
|
||||
lastSentNonzeroPcbNumber = PcbNumber;
|
||||
sendPcbNr = false;
|
||||
if (PcbNumber > 0)
|
||||
{
|
||||
parent.OnBarcodeReceived(this,
|
||||
new BarcodeReceivedEventArgs(PcbNumber.ToString(), IxPolozky, Part.CodeLocation, PartError.None));
|
||||
}
|
||||
}
|
||||
|
||||
/// Update UI
|
||||
pcbNumberTextBox.Text = (currentPcbNr > 0) ? currentPcbNr.ToString() : string.Empty; /// Always displayed
|
||||
///
|
||||
int denominator = (currentPcbNr == (Int64)(-1)) ? (int)MinBreakTime : (int)MinHoldTime;
|
||||
int numerator = Math.Min(Math.Max(0,
|
||||
Convert.ToInt32((currentPcbNr == (Int64)(-1)) ? MinBreakTime - lastValidTime + firstValidTime : lastValidTime - firstValidTime)),
|
||||
denominator);
|
||||
pcbNumberProgressBar.Value = (currentPcbNr != 0) ? (100 * numerator / denominator) : 0;
|
||||
pcbNumberProgressBar.ColorId = (currentPcbNr > 0) ? 0 : 1;
|
||||
}
|
||||
|
||||
public void RunDeviceAfter() { }
|
||||
@ -238,7 +268,7 @@ namespace Workplace.CheckItems
|
||||
{
|
||||
/// No CR+LF found =>stop processing => wait for more characters in the buffer in the next invocation
|
||||
partOfTelegram = allRcvd;
|
||||
return;
|
||||
break;
|
||||
}
|
||||
else if (pos < S640.DatastreamFrame.FrameLength - 2)
|
||||
{
|
||||
@ -247,24 +277,79 @@ namespace Workplace.CheckItems
|
||||
}
|
||||
else
|
||||
{
|
||||
bool frameOk = optoData[optoDataIx].UpdateFromString(allRcvd.Substring(pos - S640.DatastreamFrame.FrameLength + 2, S640.DatastreamFrame.FrameLength),
|
||||
ref currentRawVolumeUnwrapped, ref currentRawTimeUnwrapped);
|
||||
bool frameOk = frame.UpdateFromString(allRcvd.Substring(pos - S640.DatastreamFrame.FrameLength + 2,
|
||||
S640.DatastreamFrame.FrameLength),
|
||||
ref currentRawVolumeUnwrapped,
|
||||
ref currentRawTimeUnwrapped);
|
||||
if (frameOk)
|
||||
{
|
||||
/// Frame OK => Move to the next frame
|
||||
optoDataIx++;
|
||||
if (optoDataIx >= FramesBufferSize) optoDataIx = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/// Invalid frame => Invalidate it (age it)
|
||||
optoData[optoDataIx].DateTime = DateTime.MinValue;
|
||||
Array.Copy(frame.Data, 0, pcbNrStr, 0, 12);
|
||||
Array.Copy(frame.Data, 12, radioAddrStr, 0, 10);
|
||||
if (Int64.TryParse(new string(pcbNrStr), out currentPcbNr) && Int64.TryParse(new string(radioAddrStr), out currentRadioAddr)
|
||||
&& currentPcbNr != 0 && currentRadioAddr != 0)
|
||||
{
|
||||
if (currentRawTimeUnwrapped - lastValidTime <= MaxDropoutTime &&
|
||||
currentPcbNr == validPcbNumber &&
|
||||
currentRadioAddr == validRadioAddress &&
|
||||
currentPcbNr != lastSentNonzeroPcbNumber)
|
||||
{
|
||||
/// No datastream dropout and data have not changed: extend the validity time
|
||||
lastValidTime = currentRawTimeUnwrapped;
|
||||
|
||||
if ((lastValidTime - firstValidTime) >= MinHoldTime)
|
||||
{
|
||||
PcbNumber = validPcbNumber;
|
||||
RadioAddress = validRadioAddress;
|
||||
}
|
||||
}
|
||||
else if (currentPcbNr != lastSentNonzeroPcbNumber)
|
||||
{
|
||||
/// Either a datastream dropout or data changed: consider this frame to be the first one for evaluation
|
||||
validPcbNumber = currentPcbNr;
|
||||
validRadioAddress = currentRadioAddr;
|
||||
firstValidTime = currentRawTimeUnwrapped;
|
||||
lastValidTime = currentRawTimeUnwrapped;
|
||||
|
||||
PcbNumber = 0;
|
||||
RadioAddress = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
allRcvd = allRcvd.Substring(pos + 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (receivedBytes == 0 || currentPcbNr == lastSentNonzeroPcbNumber || currentPcbNr == (long)-1)
|
||||
{
|
||||
/// No data received (= dropout, but no new data)
|
||||
currentPcbNr = (long)-1;
|
||||
currentRadioAddr = (long)-1;
|
||||
|
||||
if (currentPcbNr == validPcbNumber && currentRadioAddr == validRadioAddress)
|
||||
{
|
||||
/// Next time
|
||||
lastValidTime = lastValidTime + (long)Const.Interval;
|
||||
}
|
||||
else
|
||||
{
|
||||
/// First time
|
||||
firstValidTime = lastValidTime + (long)Const.Interval;
|
||||
lastValidTime = firstValidTime;
|
||||
validPcbNumber = currentPcbNr;
|
||||
validRadioAddress = currentRadioAddr;
|
||||
|
||||
PcbNumber = 0;
|
||||
RadioAddress = 0;
|
||||
}
|
||||
|
||||
if ((lastValidTime - firstValidTime) >= MinBreakTime)
|
||||
{
|
||||
PcbNumber = validPcbNumber;
|
||||
RadioAddress = validRadioAddress;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@ -275,42 +360,5 @@ namespace Workplace.CheckItems
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ProcessBuffer_UpdatePcbNrAndRA()
|
||||
{
|
||||
DateTime now = DateTime.Now;
|
||||
|
||||
char[] pcbNrStr = new char[12];
|
||||
char[] radioAddrStr = new char[10];
|
||||
Int64 pcbNr;
|
||||
Int64 radioAddr;
|
||||
|
||||
prwList.Clear();
|
||||
for (int i = 0; i < FramesBufferSize; i++)
|
||||
{
|
||||
double age = (now - optoData[i].DateTime).TotalSeconds;
|
||||
if (age < 5)
|
||||
{
|
||||
Array.Copy(optoData[i].Data, 0, pcbNrStr, 0, 12);
|
||||
Array.Copy(optoData[i].Data, 12, radioAddrStr, 0, 10);
|
||||
if (Int64.TryParse(new string(pcbNrStr), out pcbNr) && Int64.TryParse(new string(radioAddrStr), out radioAddr))
|
||||
{
|
||||
S640.PcbnrRadioaddrWeight.Accumulate(prwList, pcbNr, radioAddr, 5 - age);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (prwList.Count > 0)
|
||||
{
|
||||
prwList = prwList.OrderByDescending(x => x.Weight).ToList();
|
||||
PcbNumber = prwList[0].PcbNr;
|
||||
RadioAddress = prwList[0].RadioAddr;
|
||||
}
|
||||
else
|
||||
{
|
||||
PcbNumber = 0;
|
||||
RadioAddress = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
9
Workplace/Const.cs
Normal file
9
Workplace/Const.cs
Normal file
@ -0,0 +1,9 @@
|
||||
using System;
|
||||
|
||||
namespace Workplace
|
||||
{
|
||||
public static class Const
|
||||
{
|
||||
public const int Interval = 400; /// ms
|
||||
}
|
||||
}
|
||||
@ -10,7 +10,7 @@ using System.Runtime.InteropServices;
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("Workplace")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2015-2021")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2015-2023")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("3.1.17.0")]
|
||||
[assembly: AssemblyFileVersion("3.1.17.0")]
|
||||
[assembly: AssemblyVersion("3.1.19.0")]
|
||||
[assembly: AssemblyFileVersion("3.1.19.0")]
|
||||
|
||||
@ -95,6 +95,9 @@
|
||||
<Compile Include="CheckItems\Keyboard.Designer.cs">
|
||||
<DependentUpon>Keyboard.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="CheckItems\MyProgressBar.cs">
|
||||
<SubType>Component</SubType>
|
||||
</Compile>
|
||||
<Compile Include="CheckItems\OkNok.cs">
|
||||
<SubType>UserControl</SubType>
|
||||
</Compile>
|
||||
@ -122,6 +125,7 @@
|
||||
<Compile Include="CheckItems\SNGeneratorPrinter.Designer.cs">
|
||||
<DependentUpon>SNGeneratorPrinter.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Const.cs" />
|
||||
<Compile Include="Enums.cs" />
|
||||
<Compile Include="Forms\SettingsDlg.cs">
|
||||
<SubType>Form</SubType>
|
||||
|
||||
@ -189,7 +189,7 @@ namespace Workplace
|
||||
|
||||
/// Timer for regular 1 second ticks
|
||||
runDeviceTimer = new System.Windows.Forms.Timer();
|
||||
runDeviceTimer.Interval = 1000; // ms
|
||||
runDeviceTimer.Interval = Const.Interval;
|
||||
runDeviceTimer.Tick += new EventHandler(runDeviceTimer_Tick);
|
||||
runDeviceTimer.Start();
|
||||
|
||||
@ -1315,9 +1315,17 @@ namespace Workplace
|
||||
k.ClearCode();
|
||||
k.ResetFocus();
|
||||
}
|
||||
if (komponenty.Count > 0)
|
||||
if (komponenty.Count >= 1)
|
||||
{
|
||||
komponenty[0].SetFocus();
|
||||
if (komponenty.Count >= 2 && komponenty[0] is CheckItems.SNGeneratorPrinter
|
||||
&& komponenty[0].Part.CodeForm == (sbyte)CodeForm.SNGenerator)
|
||||
{
|
||||
komponenty[1].SetFocus();
|
||||
}
|
||||
else
|
||||
{
|
||||
komponenty[0].SetFocus();
|
||||
}
|
||||
}
|
||||
|
||||
if ((recordProcessing != null) && !wasAlreadyTested && componentsSaved)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user