using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Drawing;
|
|
using System.Data;
|
|
using System.IO;
|
|
using System.IO.Ports;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
using BWP.WinFormControl.WeightDataFormat;
|
|
|
|
namespace BWP.WinFormControl.WeightControl_
|
|
{
|
|
public partial class WeightControl : UserControl
|
|
{
|
|
public ApplyTo ApplyTo { get; set; }
|
|
|
|
//定义委托
|
|
public delegate void WeightHandle(object sender, WeightEventArgu e);
|
|
//定义事件
|
|
public event WeightHandle WeightEventHandle;
|
|
|
|
public WeightControl()
|
|
{
|
|
InitializeComponent();
|
|
weightPort = new SerialPort();
|
|
|
|
_checkComStatusThread = new Thread(SetComStatus);
|
|
_checkComStatusThread.Start();
|
|
}
|
|
|
|
public void Close()
|
|
{
|
|
if (_inQueryThread != null && _inQueryThread.IsAlive)
|
|
{
|
|
DisableWeight();
|
|
}
|
|
if (_checkComStatusThread != null && _checkComStatusThread.IsAlive)
|
|
{
|
|
Thread.Sleep(10);
|
|
if (_checkComStatusThread.IsAlive)
|
|
{
|
|
_checkComStatusThread.Abort();
|
|
}
|
|
}
|
|
}
|
|
|
|
public WeightConfig WeightConfig
|
|
{
|
|
get { return WeightContext.GetConfig(ApplyTo); }
|
|
}
|
|
|
|
#region weightNeed
|
|
SerialPort weightPort;
|
|
private IDataFormat _dataFormat;
|
|
private Thread _inQueryThread;
|
|
private Thread _checkComStatusThread;
|
|
private bool _mainProcessIsRun;
|
|
readonly StringBuilder _dataStrBuilder = new StringBuilder();
|
|
|
|
readonly StringBuilder _allDataStrBuilder = new StringBuilder();
|
|
#endregion
|
|
|
|
#region weightNeed
|
|
void OpenSerialPort()
|
|
{
|
|
if (WeightConfig.RateSet == null)
|
|
{
|
|
throw new Exception("请先配置称相关信息");
|
|
}
|
|
|
|
weightPort.PortName = WeightConfig.ComSet;
|
|
weightPort.BaudRate = WeightConfig.RateSet.Value;
|
|
weightPort.DataBits = WeightConfig.BitSet;
|
|
weightPort.ReadBufferSize = 4096 * 100;
|
|
if (!string.IsNullOrEmpty(WeightConfig.Format))
|
|
{
|
|
format = "{0:{format}}".Replace("{format}", WeightConfig.Format);
|
|
}
|
|
switch (WeightConfig.WeightSet)
|
|
{
|
|
case "IND560":
|
|
_dataFormat = new IND560DataFormat();
|
|
break;
|
|
case "Xk3124":
|
|
case "IND231":
|
|
_dataFormat = new Xk3124DataFormat();
|
|
break;
|
|
case "Xk3190A9":
|
|
_dataFormat = new Xk3190A9DataFormat();
|
|
break;
|
|
default:
|
|
_dataFormat = new Xk3190D10DataFormat();
|
|
break;
|
|
}
|
|
if (!weightPort.IsOpen)
|
|
{
|
|
try
|
|
{
|
|
weightPort.Open();
|
|
}
|
|
catch (InvalidOperationException)
|
|
{
|
|
MessageBox.Show(@"指定的端口已打开");
|
|
}
|
|
catch (UnauthorizedAccessException)
|
|
{
|
|
MessageBox.Show(@"对端口的访问被拒绝");
|
|
}
|
|
}
|
|
}
|
|
|
|
void ReadData()
|
|
{
|
|
_inQueryThread = new Thread(InQuery);
|
|
_inQueryThread.Start();
|
|
}
|
|
|
|
string format = "{0:0.00}";
|
|
|
|
private void InQuery()
|
|
{
|
|
|
|
while (_mainProcessIsRun)
|
|
{
|
|
int availableCount = weightPort.BytesToRead;
|
|
if (availableCount == 0)
|
|
{
|
|
Thread.Sleep(1);
|
|
}
|
|
|
|
char[] buffer = new char[availableCount];
|
|
if (!weightPort.IsOpen)
|
|
{
|
|
continue;
|
|
}
|
|
weightPort.Read(buffer, 0, availableCount);
|
|
foreach (var c in buffer)
|
|
{
|
|
_allDataStrBuilder.Append(c);
|
|
if (c == _dataFormat.Beginchar)
|
|
{
|
|
_dataStrBuilder.Clear();
|
|
_dataStrBuilder.Append(c);
|
|
}
|
|
else if (c == _dataFormat.Endchar && _dataStrBuilder.Length == _dataFormat.DataLength - 1)
|
|
{
|
|
_dataStrBuilder.Append(c);
|
|
bool isStatic;
|
|
string str;
|
|
if (_dataFormat.ParseAscii(_dataStrBuilder.ToString(), out str, out isStatic))
|
|
{
|
|
if (WeightConfig.WeightType == 0)
|
|
{
|
|
if (string.IsNullOrEmpty(str))
|
|
str = "0";
|
|
this.Invoke(new Action(delegate ()
|
|
{
|
|
lblChengZhong.Text = string.Format(format, decimal.Parse(str));
|
|
if (str != "0")
|
|
{
|
|
if (WeightEventHandle != null)
|
|
{
|
|
var argu = new WeightEventArgu(lblChengZhong.Text, format);
|
|
WeightEventHandle(lblChengZhong, argu);
|
|
}
|
|
}
|
|
}));
|
|
}
|
|
else
|
|
{
|
|
decimal num = 0;
|
|
if (decimal.TryParse(str, out num))
|
|
{
|
|
this.Invoke(new Action(delegate ()
|
|
{
|
|
lblChengZhong.Text = string.Format(format, num);
|
|
}));
|
|
WeighAvgControl.Add(WeightConfig, num, isStatic);
|
|
}
|
|
if (WeighAvgControl.TryGetValue(out num))
|
|
{
|
|
this.Invoke(new Action(delegate ()
|
|
{
|
|
lblChengZhong.Text = string.Format(format, num);
|
|
if (str != "0")
|
|
{
|
|
if (WeightEventHandle != null)
|
|
{
|
|
var argu = new WeightEventArgu(lblChengZhong.Text, format);
|
|
WeightEventHandle(lblChengZhong, argu);
|
|
}
|
|
}
|
|
}));
|
|
}
|
|
}
|
|
}
|
|
_dataStrBuilder.Clear();
|
|
}
|
|
else if (_dataStrBuilder.Length != 0)
|
|
{
|
|
_dataStrBuilder.Append(c);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private class WeighAvgControl
|
|
{
|
|
public static bool TryGetValue(out decimal result)
|
|
{
|
|
List<Tuple<decimal, bool>> list;
|
|
if (mWeighList.TryDequeue(out list))
|
|
{
|
|
var r = list.Where(x => x.Item2).Select(x => x.Item1).GroupBy(x => x);
|
|
var firstOrDefault = r.OrderByDescending(x => x.Count()).FirstOrDefault();
|
|
if (firstOrDefault != null)
|
|
{
|
|
result = firstOrDefault.Key;
|
|
return true;
|
|
}
|
|
result = 0;
|
|
return false;
|
|
}
|
|
result = 0;
|
|
return false;
|
|
}
|
|
|
|
static ConcurrentQueue<List<Tuple<decimal, bool>>> mWeighList = new ConcurrentQueue<List<Tuple<decimal, bool>>>();
|
|
|
|
static List<Tuple<decimal, bool>> _list = new List<Tuple<decimal, bool>>();
|
|
|
|
public static void Add(WeightConfig weightConfig, decimal value, bool isStatic)
|
|
{
|
|
if (value >= weightConfig.MinWeight && value <= weightConfig.MaxWeight)
|
|
{
|
|
_list.Add(new Tuple<decimal, bool>(value, isStatic));
|
|
}
|
|
else
|
|
{
|
|
if (_list.Count > 0)
|
|
{
|
|
mWeighList.Enqueue(_list);
|
|
_list = new List<Tuple<decimal, bool>>();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void DisableWeight()
|
|
{
|
|
_mainProcessIsRun = false;
|
|
lblChengZhong.Text = string.Format(format, 0);
|
|
format = "{0:0.00}";
|
|
if (WeightEventHandle != null)
|
|
{
|
|
var argu = new WeightEventArgu(lblChengZhong.Text, format);
|
|
WeightEventHandle(lblChengZhong, argu);
|
|
}
|
|
Thread.Sleep(10);
|
|
if (_inQueryThread.IsAlive)
|
|
{
|
|
_inQueryThread.Abort();
|
|
}
|
|
if (weightPort.IsOpen)
|
|
weightPort.Close();
|
|
}
|
|
#endregion
|
|
|
|
|
|
private void SetComStatus()
|
|
{
|
|
while (true)
|
|
{
|
|
try
|
|
{
|
|
var png = "stop.png";
|
|
|
|
if (_allDataStrBuilder.Length > 0)
|
|
{
|
|
png = "working.png";
|
|
_allDataStrBuilder.Clear();
|
|
}
|
|
var imgPath = Path.Combine(Application.StartupPath, "BWP.WinFormControl.dll");
|
|
var s = Assembly.LoadFile(imgPath).GetManifestResourceStream("BWP.WinFormControl.Images." + png);
|
|
if (this.InvokeRequired)
|
|
{
|
|
this.BeginInvoke(new Action(() =>
|
|
{
|
|
picNetStatus.Image = Image.FromStream(s);
|
|
picNetStatus.Refresh();
|
|
}));
|
|
}
|
|
else
|
|
{
|
|
picNetStatus.Image = Image.FromStream(s);
|
|
picNetStatus.Refresh();
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
//LogUtil.Error(e.ToString());
|
|
}
|
|
|
|
Thread.Sleep(500);
|
|
}
|
|
}
|
|
|
|
|
|
private void btnWeightSet_Click(object sender, EventArgs e)
|
|
{
|
|
var f = new WeightSetForm(ApplyTo);
|
|
if (f.ShowDialog() == DialogResult.OK)
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
private void btnStartWeight_Click(object sender, EventArgs e)
|
|
{
|
|
_mainProcessIsRun = true;
|
|
OpenSerialPort();
|
|
ReadData();
|
|
btnStartWeight.Enabled = false;
|
|
btnEndWeight.Enabled = true;
|
|
}
|
|
|
|
private void btnEndWeight_Click(object sender, EventArgs e)
|
|
{
|
|
DisableWeight();
|
|
btnStartWeight.Enabled = true;
|
|
btnEndWeight.Enabled = false;
|
|
}
|
|
}
|
|
}
|