using System;
|
|
using System.Collections.Generic;
|
|
using System.ComponentModel;
|
|
using System.Drawing;
|
|
using System.Data;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Windows.Forms;
|
|
using System.IO.Ports;
|
|
using System.Threading;
|
|
using System.Collections.Concurrent;
|
|
using ButcherFactory.Utils;
|
|
|
|
namespace ButcherFactory.Controls
|
|
{
|
|
public partial class WeightControl : UserControl
|
|
{
|
|
WeightConfig config;
|
|
SerialPort weightPort;
|
|
IDataFormat _dataFormat;
|
|
Thread _inQueryThread;
|
|
private bool _mainProcessIsRun;
|
|
readonly StringBuilder _dataStrBuilder = new StringBuilder();
|
|
private bool switchOn;
|
|
|
|
[Browsable(true), Description("称设置标识")]
|
|
public string WeightFalg { get; set; }
|
|
|
|
[Browsable(true), Description("读取到值的事件")]
|
|
public event Action<decimal> ReceivedValue;
|
|
|
|
[Browsable(false)]
|
|
public decimal Weight
|
|
{
|
|
get
|
|
{
|
|
var v = decimal.Parse(lblChengZhong.Text);
|
|
if (config != null)
|
|
v -= (config.Discont ?? 0);
|
|
return v;
|
|
}
|
|
}
|
|
|
|
public WeightControl()
|
|
{
|
|
InitializeComponent();
|
|
}
|
|
|
|
protected override void OnLoad(EventArgs e)
|
|
{
|
|
base.OnLoad(e);
|
|
var parentForm = ControlsUtil.GetParentFormm(this);
|
|
if (parentForm != null)
|
|
{
|
|
parentForm.FormClosing += delegate
|
|
{
|
|
if (_inQueryThread != null && _inQueryThread.IsAlive)
|
|
{
|
|
DisableWeight();
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
private void settingBtn_Click(object sender, EventArgs e)
|
|
{
|
|
if (new WeightSettingFrom(WeightFalg).ShowDialog() == DialogResult.OK)
|
|
config = WeightConfig.Init(WeightFalg);
|
|
}
|
|
|
|
private void weightSwitch_Click(object sender, EventArgs e)
|
|
{
|
|
try
|
|
{
|
|
if (config == null)
|
|
{
|
|
config = WeightConfig.Init(WeightFalg);
|
|
WeighAvgControl.config = config;
|
|
}
|
|
settingBtn.Enabled = switchOn;
|
|
switchOn = !switchOn;
|
|
ChangeWeightBtnState();
|
|
if (switchOn)
|
|
{
|
|
OpenSerialPort();
|
|
_mainProcessIsRun = true;
|
|
ReadData();
|
|
}
|
|
else
|
|
{
|
|
DisableWeight();
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
switchOn = !switchOn;
|
|
settingBtn.Enabled = !switchOn;
|
|
ChangeWeightBtnState();
|
|
throw;
|
|
}
|
|
finally
|
|
{
|
|
this.Focus();
|
|
}
|
|
}
|
|
|
|
void ChangeWeightBtnState()
|
|
{
|
|
if (switchOn)
|
|
weightSwitch.Text = "停止称重";
|
|
else
|
|
weightSwitch.Text = "启用称重";
|
|
}
|
|
|
|
void OpenSerialPort()
|
|
{
|
|
if (!switchOn)
|
|
return;
|
|
if (config.RateSet == null)
|
|
throw new Exception("请先配置称相关信息");
|
|
weightPort = new SerialPort();
|
|
weightPort.PortName = config.ComSet;
|
|
weightPort.BaudRate = config.RateSet.Value;
|
|
weightPort.DataBits = config.BitSet.Value;
|
|
weightPort.ReadBufferSize = 4096 * 100;
|
|
if (!string.IsNullOrEmpty(config.Format))
|
|
format = "{0:{format}}".Replace("{format}", config.Format);
|
|
|
|
switch (config.WeightSet)
|
|
{
|
|
case "IND560":
|
|
_dataFormat = new IND560DataFormat();
|
|
break;
|
|
case "AHS3000":
|
|
_dataFormat = new AoHaoSi3000DataFormat();
|
|
break;
|
|
case "Xk3124":
|
|
case "IND231":
|
|
_dataFormat = new Xk3124DataFormat();
|
|
break;
|
|
case "Xk3190A9":
|
|
_dataFormat = new Xk3190A9DataFormat();
|
|
break;
|
|
case "JST2018S":
|
|
_dataFormat = new JST2018SDataFormat();
|
|
break;
|
|
case "一体称"://02 10 53 54 2C 47 53 3A 20 30 30 30 31 2E 37 31 6B 67 A8 FE 00 49 01 00 AC 99 A8 FE 00
|
|
_dataFormat = new CombineWeightDataFormat();
|
|
break;
|
|
default:
|
|
_dataFormat = new Xk3190D10DataFormat();
|
|
break;
|
|
}
|
|
if (!weightPort.IsOpen)
|
|
{
|
|
try
|
|
{
|
|
weightPort.Open();
|
|
}
|
|
catch (InvalidOperationException)
|
|
{
|
|
throw new Exception("指定的端口已打开");
|
|
}
|
|
catch (UnauthorizedAccessException)
|
|
{
|
|
throw new Exception("对端口的访问被拒绝");
|
|
}
|
|
}
|
|
}
|
|
|
|
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(10);
|
|
}
|
|
byte[] buffer = new byte[availableCount];
|
|
weightPort.Read(buffer, 0, availableCount);
|
|
foreach (var b in buffer)
|
|
{
|
|
var c = (char)b;
|
|
if (c == _dataFormat.Beginchar)
|
|
{
|
|
_dataStrBuilder.Clear();
|
|
_dataStrBuilder.Append(c);
|
|
}
|
|
//针对JST2018不合适,需要改成&&
|
|
else if (c == _dataFormat.Endchar || _dataStrBuilder.Length >= _dataFormat.Bufsize)
|
|
{
|
|
_dataStrBuilder.Append(c);
|
|
bool isStatic;
|
|
string str;
|
|
if (_dataFormat.ParseAscii(_dataStrBuilder.ToString(), out str, out isStatic))
|
|
{
|
|
if (config.WeightType == 0)
|
|
{
|
|
if (string.IsNullOrEmpty(str))
|
|
str = "0";
|
|
this.Invoke(new Action(delegate()
|
|
{
|
|
decimal v = 0;
|
|
decimal.TryParse(str, out v);
|
|
lblChengZhong.Text = string.Format(format, v);
|
|
if (str != "0")
|
|
{
|
|
if (ReceivedValue != null)
|
|
ReceivedValue(v - (config.Discont ?? 0));
|
|
}
|
|
}));
|
|
}
|
|
else
|
|
{
|
|
decimal num = 0;
|
|
if (decimal.TryParse(str, out num))
|
|
{
|
|
this.Invoke(new Action(delegate()
|
|
{
|
|
lblChengZhong.Text = string.Format(format, num);
|
|
}));
|
|
WeighAvgControl.Add(num, isStatic);
|
|
}
|
|
if (WeighAvgControl.TryGetValue(out num))
|
|
{
|
|
this.Invoke(new Action(delegate()
|
|
{
|
|
if (str != "0")
|
|
{
|
|
if (ReceivedValue != null)
|
|
ReceivedValue(num - (config.Discont ?? 0));
|
|
}
|
|
}));
|
|
}
|
|
}
|
|
}
|
|
_dataStrBuilder.Clear();
|
|
}
|
|
else
|
|
{
|
|
_dataStrBuilder.Append(c);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private class WeighAvgControl
|
|
{
|
|
public static WeightConfig config;
|
|
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(decimal value, bool isStatic)
|
|
{
|
|
if (value >= config.MinWeight && value <= config.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}";
|
|
Thread.Sleep(10);
|
|
if (_inQueryThread.IsAlive)
|
|
{
|
|
_inQueryThread.Abort();
|
|
}
|
|
if (weightPort.IsOpen)
|
|
weightPort.Close();
|
|
}
|
|
}
|
|
}
|