using Aitex.Core.RT.Device; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.Routine; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using athosRT.tool; using MECF.Framework.Common.Communications; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.OcrReaders.HST; using System; using System.Collections.Generic; using System.IO.Ports; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading; using System.Threading.Tasks; using OP = Common.OP.OP; using DATA = Common.DataCenter.DATA; using FabConnect.SecsGemInterface.Application.Objects.ObjectService; namespace athosRT.Devices { public class Ffu : BaseDevice, IDevice, IConnection { private static SerialPort _port; private readonly object _locker = new object(); private int _nMaxSpeed; public int NMaxSpeed => _nMaxSpeed; private int _ffuSpeed = 0; public int FFUSpeed { get { return _ffuSpeed; } set { _ffuSpeed = value; } } public Ffu(string module, string name, string station, string port) : base(module, name, name, "") { Ffu._port = new SerialPort() { PortName = port, BaudRate = 9600, DataBits = 8, Parity = Parity.None, StopBits = StopBits.One, RtsEnable = false, DtrEnable = false, ReadTimeout = 1000, WriteTimeout = 1000, NewLine = "\r", Handshake = Handshake.None }; Ffu._port.DataReceived += new SerialDataReceivedEventHandler(this.OnDataChanged); Ffu._port.ErrorReceived += new SerialErrorReceivedEventHandler(this.OnErrorHandler); this.Initalized = false; this.Station = station; this.Address = port; //this.Initialize(); } public static bool SpeedSet1 { get; private set; } public static bool SpeedSet2 { get; private set; } public string Station { get; } public bool Initalized { get; set; } public string Address { get; } public bool IsConnected => Ffu._port.IsOpen; public bool Connect() { Task.Factory.StartNew((Action)(() => { int num1 = SC.ContainsItem("System.ComPortRetryCount") ? SC.GetValue("System.ComPortRetryCount") : 3; int num2 = SC.ContainsItem("System.ComPortRetryDelayTime") ? SC.GetValue("System.ComPortRetryDelayTime") : 2; if (num2 <= 0 || num2 > 10) num2 = 2; int num3 = 0; while (!this.Open()) { if (num1 > 0 && num3++ > num1) { LogObject.Info(GetName.GetCurrentName(),"Retry connect " + this.Module + "." + this.Name + " stop retry."); EV.PostAlarmLog(this.Module, "Can't connect to " + this.Module + "." + this.Name + "."); return; } Thread.Sleep(num2 * 1000);//原本就有 LogObject.Info(GetName.GetCurrentName(),string.Format("Retry connect {0}.{1} for the {2} time.", (object)this.Module, (object)this.Name, (object)(num3 + 1))); } EV.PostInfoLog(GetName.GetCurrentName(),this.Module, "Connected with " + this.Module + "." + this.Name + " ."); })); return true; } public bool Disconnect() => true; private PeriodicJob _thread; public bool Initialize() { Singleton.Instance.Subscribe(this.Name ?? "", (IConnection)this); _nMaxSpeed = SC.GetValue("System.FFU.MaxSpeed"); this.Connect(); _thread = new PeriodicJob(1000, OnTimer, base.Name + " MonitorHandler", isStartNow: true); DATA.Subscribe(base.Name + ".FFUSpeed", () => _ffuSpeed); this.RegisterOperation(); return true; } private bool OnTimer() { this.QuerySpeed(); return true; } public void Monitor() { } public void Terminate() => this.Close(); public void Reset() { } private void OnDataChanged( object sender, SerialDataReceivedEventArgs serialDataReceivedEventArgs) { try { if (!_port.IsOpen) return; BinaryDataReceived(); } catch (Exception ex) { //LogObject.Error(GetName.GetCurrentName(), " " + this.Name + " has exception:" + ex.Message); } } public void BinaryDataReceived() { byte[] readBuffer = new byte[_port.BytesToRead]; int readCount = _port.Read(readBuffer, 0, readBuffer.Length); if (readCount == 0) { //LOG.Write($"read zero length data, {_port.PortName}"); return; } byte[] buffer = new byte[readCount]; Buffer.BlockCopy(readBuffer, 0, buffer, 0, readCount); StringBuilder str = new StringBuilder(512); Array.ForEach(buffer, x => str.Append(x.ToString("X2") + " ")); if (buffer[0] == 0x31) { if (buffer.Length >= 4) { FFUSpeed = ((int)buffer[3]) * NMaxSpeed / 250; Ffu.SpeedSet1 = true; // EV.PostInfoLog(this.Module, "FFU read speed "+ FFUSpeed+":" + str.ToString()); } } else if (buffer[0] == 0x11) { EV.PostInfoLog(this.Module,"FFU's speed is successfully set:" +str.ToString()); } //switch (buffer[0].ToString("X2")) //{ // case "31": // if (buffer.Length >= 4) { // FFUSpeed =((int) buffer[3]) * NMaxSpeed / 250; // } // break; //} // } private void OnErrorHandler( object sender, SerialErrorReceivedEventArgs serialErrorReceivedEventArgs) { this.Initalized = false; EV.PostAlarmLog(this.Module, string.Format("{0} Communication error, {1}", (object)this.Display, (object)serialErrorReceivedEventArgs)); } private void RegisterOperation() { OP.Subscribe(this.Name + ".SetSpeed", (Func)((cmd, param) => { int result= (int) param[0]; //if (!int.TryParse((string)param[0], out result)) //{ // EV.PostWarningLogl(this.Module, "invalid speed."); // return false; //} this.StartAndSetSpeed(result); EV.PostInfoLog(this.Module, string.Format("{0} speed set to {1}", (object)this.Name, (object)result)); return true; })); OP.Subscribe(this.Name + ".CheckSpeed", (Func)((cmd, param) => { this.QuerySpeed(); EV.PostInfoLog(this.Module, "Query " + this.Name + " speed"); return true; })); } public void StartAndSetSpeed(int speed) { lock (this._locker) { List baseBytes = new List() { 0x35, 0x41, 0x01 }; int ffuspeed = speed * 250 / _nMaxSpeed; byte[] bytes = BitConverter.GetBytes(ffuspeed); baseBytes.Add(bytes[0]); baseBytes.Add(ModRTU_CRC(baseBytes.ToArray())); byte[] arr = baseBytes.ToArray(); Ffu.SpeedSet1 = false; if (_port.IsOpen) { _port.Write(arr, 0, arr.Length); } } } public void QuerySpeed() { lock (this._locker) { List baseBytes = new List() { 0x15, 0x21, 0x01, 0xCA }; byte[] arr = baseBytes.ToArray(); //string array = "15 21 01 CA"; if (_port.IsOpen) { _port.Write(arr, 0, arr.Length); // this.SendLog.AppendText(array + "\n"); } } } public static string[] ParseSpeed(int speed) { byte[] bytes = BitConverter.GetBytes(speed); return new string[2] { bytes[1].ToString("X").Length < 2 ? string.Format("0{0:X}", (object) bytes[1]) : string.Format("{0:X}", (object) bytes[1]), bytes[0].ToString("X").Length < 2 ? string.Format("0{0:X}", (object) bytes[0]) : string.Format("{0:X}", (object) bytes[0]) }; } private bool Open() { lock (this._locker) { if (Ffu._port.IsOpen) this.Close(); try { Ffu._port.Open(); Ffu._port.DiscardInBuffer(); Ffu._port.DiscardOutBuffer(); } catch (Exception ex) { LogObject.Error(GetName.GetCurrentName(),Ffu._port.PortName + " port open failed,please check configuration。" + ex.Message); return false; } } return true; } private bool Close() { lock (this._locker) { if (Ffu._port.IsOpen) { try { Ffu._port.Close(); } catch (Exception ex) { EV.PostInfoLog(this.Module, Ffu._port.PortName + " port close failed。" + ex.Message); return false; } } } return true; } private static byte ModRTU_CRC(byte[] buffer) { int num = buffer.Length; byte b = buffer[0]; for (int i = 1; i < buffer.Length; i++) { b = (byte)(b ^ buffer[i]); } return (byte)(~b); } } }