using System;
|
using System.Collections.Generic;
|
using System.IO.Ports;
|
using System.Linq;
|
using System.Text;
|
using System.Threading;
|
using System.Threading.Tasks;
|
using System.Timers;
|
using TProduct.Model;
|
|
namespace TProduct.Link.Kedi
|
{
|
/// <summary>
|
/// 丹泉
|
/// </summary>
|
public class SiSingleComLinkHelper : TProduct.Link.LinkItemBaseHelper, IDisposable
|
{
|
private SerialPort _defaultComPort = null;
|
private List<WorkBenchInstrumentKedi> _instrumentParas = null;
|
|
private List<TProduct.Model.WorkBenchMonitorPoint> _allMonitorPoints = null;
|
protected int _receiveWaitTime = 180;//等待时间
|
protected int _tTimerParas = 300;//定时器轮询时间
|
protected System.Timers.Timer _tTimer;
|
|
private SiMsg电参数 _sSiMsg电参数 = null;
|
private SiMsg阀门 _sSiMsg阀门 = null;
|
private SiMsg流量转速 _sSiMsg流量转速 = null;
|
private SiMsg压力 _sSiMsg压力 = null;
|
|
//端口数
|
private int _itemCount = 0;
|
//当前
|
private int _currentItemIndex = 0;
|
|
|
//所有可以用于测量的端口
|
private List<LinkMsgItemBase> _allItemList = null;
|
private class LinkMsgItemBase
|
{
|
public byte[] SendMessage { get; set; }
|
public string Tag { get; set; }
|
}
|
|
/// <summary>
|
/// 构造函数
|
/// </summary>
|
public SiSingleComLinkHelper()
|
{
|
|
}
|
|
/// <summary>
|
/// 构建设备
|
/// </summary>
|
/// <param name="ComName"></param>
|
/// <param name="instrumentParas"></param>
|
/// <param name="error_info"></param>
|
/// <returns></returns>
|
public bool InitialData(
|
string ComName,
|
List<Model.WorkBenchInstrumentKedi> instrumentParas,
|
List<TProduct.Model.WorkBenchMonitorPoint> allMonitors,
|
out string error_info)
|
{
|
this._instrumentParas = instrumentParas;
|
this._allMonitorPoints = allMonitors;
|
if (allMonitors == null || allMonitors.Count() == 0)
|
{
|
error_info = "测点配置为空";
|
return false;
|
}
|
var instrumentParas电 = instrumentParas.Find(x => x.LinkInstrumentTag == "电");
|
var instrumentParas压力 = instrumentParas.Find(x => x.LinkInstrumentTag == "压力");
|
var instrumentParas流量转速 = instrumentParas.Find(x => x.LinkInstrumentTag == "流量转速");
|
var instrumentParas阀门 = instrumentParas.Find(x => x.LinkInstrumentTag == "阀门");
|
_allItemList = new List<LinkMsgItemBase>();
|
if (instrumentParas电 != null)
|
{
|
_sSiMsg电参数 = new SiMsg电参数();
|
|
LinkMsgItemBase item = new LinkMsgItemBase();
|
item.SendMessage = _sSiMsg电参数.BuildBuildQueryMsg(1);
|
item.Tag = "电参数";
|
_allItemList.Add(item);
|
}
|
|
if (instrumentParas压力 != null)
|
{
|
_sSiMsg压力 = new SiMsg压力();
|
|
LinkMsgItemBase item = new LinkMsgItemBase();
|
item.SendMessage = _sSiMsg压力.BuildBuildQueryMsg( );
|
item.Tag = "压力";
|
_allItemList.Add(item);
|
}
|
|
if (instrumentParas流量转速 != null)
|
{
|
_sSiMsg流量转速 = new SiMsg流量转速();
|
|
LinkMsgItemBase item = new LinkMsgItemBase();
|
item.SendMessage = _sSiMsg流量转速.BuildBuildQueryMsg();
|
item.Tag = "流量转速";
|
|
_allItemList.Add(item);
|
}
|
|
return InitialComPort(ComName,9600, out error_info);
|
}
|
|
/// <summary>
|
///
|
/// </summary>
|
/// <param name="error_info"></param>
|
/// <returns></returns>
|
private bool InitialComPort(string ComPortName, int BaudRate, out string error_info)
|
{
|
if (BaudRate<10)
|
BaudRate = 9600;//默认
|
|
_defaultComPort = new SerialPort();
|
_defaultComPort.BaudRate = BaudRate;
|
_defaultComPort.PortName = ComPortName;
|
_defaultComPort.DataBits = 8;
|
_defaultComPort.Parity = Parity.None;
|
_defaultComPort.StopBits = StopBits.One;
|
_defaultComPort.ReceivedBytesThreshold = 1;
|
|
if (_defaultComPort.IsOpen)
|
{
|
error_info = string.Format("{0}串口已被占用,请关闭后再打开", ComPortName);
|
return false;
|
}
|
error_info = null;
|
return true;
|
}
|
|
/// <summary>
|
/// 初始化定时器
|
/// </summary>
|
protected void InitialTimer()
|
{
|
if (_tTimer != null)
|
{
|
_tTimer.Close(); _tTimer.Dispose();
|
}
|
//设置通讯周期
|
_tTimer = new System.Timers.Timer();
|
_tTimer.Interval = _tTimerParas;//!通讯间隔时间
|
_tTimer.Enabled = true;//是否执行System.Timers.Timer.Elapsed事件
|
_tTimer.Elapsed += new System.Timers.ElapsedEventHandler(OnSendMessage);//到达时间的时候执行事件;
|
_tTimer.AutoReset = true;//设置是执行一次(false)还是一直执行(true)
|
}
|
|
/// <summary>
|
/// 发送消息
|
/// </summary>
|
/// <param name="source"></param>
|
/// <param name="e"></param>
|
private void OnSendMessage(object source, System.Timers.ElapsedEventArgs e)
|
{
|
if (_isSendCtrlMsg)
|
return;
|
//判断是否到顶
|
if (_currentItemIndex >= _itemCount)
|
_currentItemIndex = 0;
|
|
//得到当前设备
|
LinkMsgItemBase currentItem = _allItemList[_currentItemIndex];
|
|
try
|
{
|
//清除
|
this._defaultComPort.DiscardOutBuffer();
|
this._defaultComPort.DiscardInBuffer();
|
|
//
|
byte[] send_message = currentItem.SendMessage;
|
if (send_message == null || send_message.Length < 1)
|
{
|
_currentItemIndex++;
|
return;
|
}
|
//
|
_currentItemIndex++;
|
|
//发送查询
|
this._defaultComPort.Write(send_message, 0, send_message.Length);
|
|
//显示
|
if (IsDispMessage && OnDisplayMsg != null)
|
{
|
OnDisplayMsg("SEND SUCCESS:::" + BitConverter.ToString(send_message));
|
}
|
|
|
|
//直接去取数据,不用事件
|
ReceiveMessage(currentItem.Tag);
|
}
|
catch (Exception ex)
|
{
|
if (IsDispMessage && OnDisplayMsg != null)
|
{
|
OnDisplayMsg("SEND ERROR:::" + ex.Message);
|
}
|
}
|
}
|
|
//正在发送控制指令
|
private bool _isSendCtrlMsg = false;
|
|
/// <summary>
|
/// 开始
|
/// </summary>
|
/// <param name="error_info"></param>
|
/// <returns></returns>
|
public override bool Start(out string error_info)
|
{
|
if (_defaultComPort == null)
|
{
|
error_info = "未初始化Com口信息";
|
return false;
|
}
|
try
|
{
|
//初始化端口
|
if (_defaultComPort.IsOpen)
|
{
|
error_info = "串口已打开,请关闭后再打开";
|
return false;
|
}
|
|
//使用事件接收
|
//defaultCom.DataReceived += new System.IO.Ports.SerialDataReceivedEventHandler(this.OnReceiveMessage);
|
_defaultComPort.Open();//打开串口
|
|
//初始化定时器
|
InitialTimer();
|
}
|
catch (Exception ex)
|
{
|
error_info = ex.Message + ",Error:225";
|
return false;
|
}
|
|
error_info = null;
|
return true;
|
}
|
|
/// <summary>
|
/// 接受消息
|
/// </summary>
|
private void ReceiveMessage(string tag)
|
{
|
try
|
{
|
//暂停200毫秒等一条完整的命令进入缓冲区:
|
Thread.Sleep(_receiveWaitTime);
|
|
//读取串口中的数据,最少也是6位
|
int count = this._defaultComPort.BytesToRead;
|
if (count < 1)
|
return;
|
|
//读取信号
|
byte[] recMessage = new byte[count];
|
this._defaultComPort.Read(recMessage, 0, recMessage.Length);
|
|
|
|
string error_info = null;
|
if(tag == "电参数")
|
{
|
#region 电参数
|
double value功率; double value电压; double value电流;
|
error_info = _sSiMsg电参数.AbstactByteValue(recMessage, out value功率, out value电压, out value电流);
|
if (string.IsNullOrEmpty(error_info))
|
{//成功
|
List<MonitorPointValue> results = new List<MonitorPointValue>();
|
|
var monitor功率 = _allMonitorPoints.Find(x=>x.MonitorType == eMonitorType.功率
|
&& (string.IsNullOrEmpty(x.Property) || x.Property == TProduct.Model.MonitorTypeProperty.总));
|
if(monitor功率 != null)
|
{
|
results.Add(monitor功率.BuildValue(value功率));
|
}
|
|
var monitor电压 = _allMonitorPoints.Find(x => x.MonitorType == eMonitorType.相电压
|
&& (string.IsNullOrEmpty(x.Property) || x.Property == TProduct.Model.MonitorTypeProperty.总));
|
if (monitor电压 != null)
|
{
|
results.Add(monitor电压.BuildValue(value电压));
|
}
|
|
var monitor电流 = _allMonitorPoints.Find(x => x.MonitorType == eMonitorType.相电流
|
&& (string.IsNullOrEmpty(x.Property) || x.Property == TProduct.Model.MonitorTypeProperty.总));
|
if (monitor电流 != null)
|
{
|
results.Add(monitor电流.BuildValue(value电流));
|
}
|
//如果成功通知界面
|
InvokeReceiveMsg(results, error_info, recMessage);
|
|
//显示信号
|
if (IsDispMessage && OnDisplayMsg != null)
|
{
|
OnDisplayMsg("GET SUCCESS:::" + BitConverter.ToString(recMessage));
|
}
|
}
|
else
|
{//失败
|
if (IsDispMessage && OnDisplayMsg != null)
|
{
|
OnDisplayMsg("GET FAIL:::" + BitConverter.ToString(recMessage) + ":::" + error_info);
|
}
|
}
|
#endregion
|
}
|
|
if (tag == "流量转速")
|
{
|
#region 流量转速
|
double value流量; double value转速;
|
error_info = _sSiMsg流量转速.AbstactByteValue(recMessage, out value流量, out value转速);
|
if (string.IsNullOrEmpty(error_info))
|
{//成功
|
List<MonitorPointValue> results = new List<MonitorPointValue>();
|
|
var monitor流量 = _allMonitorPoints.Find(x => x.MonitorType == eMonitorType.流量 );
|
if (monitor流量 != null)
|
{
|
results.Add(monitor流量.BuildValue(value流量));
|
}
|
|
var monitor转速 = _allMonitorPoints.Find(x => x.MonitorType == eMonitorType.转速);
|
if (monitor转速 != null)
|
{
|
results.Add(monitor转速.BuildValue(value转速));
|
}
|
|
|
//如果成功通知界面
|
InvokeReceiveMsg(results, error_info, recMessage);
|
|
//显示信号
|
if (IsDispMessage && OnDisplayMsg != null)
|
{
|
OnDisplayMsg("GET SUCCESS:::" + BitConverter.ToString(recMessage));
|
}
|
}
|
else
|
{//失败
|
if (IsDispMessage && OnDisplayMsg != null)
|
{
|
OnDisplayMsg("GET FAIL:::" + BitConverter.ToString(recMessage) + ":::" + error_info);
|
}
|
}
|
#endregion
|
}
|
|
if (tag == "压力")
|
{
|
#region 压力
|
double value进口_ma; double value出口_ma;
|
error_info = _sSiMsg压力.AbstactByteValue(recMessage, out value进口_ma, out value出口_ma);
|
if (string.IsNullOrEmpty(error_info))
|
{//成功
|
List<MonitorPointValue> results = new List<MonitorPointValue>();
|
|
var monitor进口 = _allMonitorPoints.Find(x => x.MonitorType == eMonitorType.压力 && ( x.Property == TProduct.Model.MonitorTypeProperty.进口));
|
if (monitor进口 != null && monitor进口.AnalogParas != null)
|
{
|
var value进口 = (value进口_ma - 4) / (monitor进口.AnalogParas.RangeMax - monitor进口.AnalogParas.RangeMin) + monitor进口.AnalogParas.RangeMin;
|
results.Add(monitor进口.BuildValue(Math.Round(value进口,5)));
|
}
|
|
var monitor出口 = _allMonitorPoints.Find(x => x.MonitorType == eMonitorType.压力 && (x.Property == TProduct.Model.MonitorTypeProperty.出口));
|
if (monitor出口 != null && monitor出口.AnalogParas != null)
|
{
|
var value出口 = (value出口_ma - 4) / (monitor出口.AnalogParas.RangeMax - monitor出口.AnalogParas.RangeMin) + monitor出口.AnalogParas.RangeMin;
|
results.Add(monitor出口.BuildValue(Math.Round(value出口, 5)));
|
}
|
|
|
//如果成功通知界面
|
InvokeReceiveMsg(results, error_info, recMessage);
|
|
//显示信号
|
if (IsDispMessage && OnDisplayMsg != null)
|
{
|
OnDisplayMsg("GET SUCCESS:::" + BitConverter.ToString(recMessage));
|
}
|
}
|
else
|
{//失败
|
if (IsDispMessage && OnDisplayMsg != null)
|
{
|
OnDisplayMsg("GET FAIL:::" + BitConverter.ToString(recMessage) + ":::" + error_info);
|
}
|
}
|
#endregion
|
}
|
}
|
catch (Exception ex)
|
{
|
if (IsDispMessage && OnDisplayMsg != null)
|
{
|
OnDisplayMsg("GET ERROR :::280:::" + ex.Message);
|
}
|
}
|
}
|
|
/// <summary>
|
/// 发送控制消息
|
/// </summary>
|
/// <param name="error_info"></param>
|
/// <returns></returns>
|
public override bool SendCtrlMsg(string tag, string paras, out string error_info)
|
{
|
if (_sSiMsg阀门 != null && tag == "阀门开度" && !string.IsNullOrEmpty(paras))
|
{
|
try
|
{
|
byte[] send_message = _sSiMsg阀门.BuildBuildQueryMsg(Convert.ToDouble(paras));
|
if (send_message == null || send_message.Length < 1)
|
{
|
error_info = "阀门开度控制指令构建失败";
|
return false;
|
}
|
if (!this._defaultComPort.IsOpen)
|
{
|
error_info = "COM口已关闭";
|
return false;
|
}
|
//
|
_isSendCtrlMsg = true;
|
|
//清除
|
this._defaultComPort.DiscardOutBuffer();
|
this._defaultComPort.DiscardInBuffer();
|
|
|
//发送查询
|
this._defaultComPort.Write(send_message, 0, send_message.Length);
|
|
//显示
|
if (IsDispMessage && OnDisplayMsg != null)
|
{
|
OnDisplayMsg("阀门开度控制 SEND SUCCESS:::" + BitConverter.ToString(send_message));
|
}
|
|
Thread.Sleep(200);
|
|
_isSendCtrlMsg = false;
|
}
|
finally
|
{
|
_isSendCtrlMsg = false;
|
}
|
|
}
|
error_info = null;
|
return true ;
|
}
|
|
/// <summary>
|
/// 关闭COM口
|
/// </summary>
|
public override bool Stop(out string error_info)
|
{
|
if (_tTimer != null)
|
{
|
_tTimer.Close(); _tTimer.Dispose();
|
Thread.Sleep(400);
|
_tTimer = null;
|
}
|
|
if (_defaultComPort != null)
|
{
|
if (_defaultComPort.IsOpen)
|
{
|
_defaultComPort.Close();
|
}
|
//_defaultComPort = null;//可能重新开启,所以不要赋值空
|
}
|
error_info= null;
|
return true;
|
}
|
|
/// <summary>
|
///
|
/// </summary>
|
public void Dispose()
|
{
|
string strInfo;
|
Stop(out strInfo);
|
}
|
}
|
|
|
}
|