using System; using System.Collections.Generic; using Aitex.Core.RT.DataCenter; using Aitex.Core.RT.Device; using Aitex.Core.RT.Event; using Aitex.Core.RT.Log; using Aitex.Core.RT.OperationCenter; using Aitex.Core.RT.SCCore; using Aitex.Core.Util; using MECF.Framework.Common.Communications; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.FFUs.MayAir; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts; using MECF.Framework.RT.EquipmentLibrary.HardwareUnits.LoadPorts.TDK; namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.FlowMeters { public class Usf500N : BaseDevice, IConnection, IDevice { private Usf500NConnection _connection; public byte DeviceAddress { get; set; } public FlowMeterData[] FlowMeterDataSet; public FlowMeterData GetFlowMeterData(string flowname) { foreach(var fdata in FlowMeterDataSet) { if (fdata.FlowName == flowname) return fdata; } return new FlowMeterData(); } private R_TRIG _trigCommunicationError = new R_TRIG(); private R_TRIG _trigRetryConnect = new R_TRIG(); private PeriodicJob _thread; private LinkedList _lstHandler = new LinkedList(); private object _locker = new object(); private bool _enableLog = true; public string Address { get; set; } public bool IsConnected { get { return _connection != null && _connection.IsConnected; } } public bool Connect() { return true; } public bool Disconnect() { return true; } public Usf500N(string module, string name, Usf500NConnection conn, Tuple[] addressChannel) : base(module, name, name, name) { _connection = conn; List tempset = new List(); foreach (var addCh in addressChannel) { FlowMeterData data = new FlowMeterData(addCh.Item1, addCh.Item2,addCh.Item3); tempset.Add(data); } FlowMeterDataSet = tempset.ToArray(); } public Usf500N(string module, string name, string comPort, Tuple[] addressChannel) : base(module, name, name, name) { _connection = new Usf500NConnection(comPort); List tempset = new List(); foreach (var addCh in addressChannel) { FlowMeterData data = new FlowMeterData(addCh.Item1, addCh.Item2, addCh.Item3); tempset.Add(data); } FlowMeterDataSet = tempset.ToArray(); } public void QuerySpeed() { foreach(var flowdata in FlowMeterDataSet) { _lstHandler.AddLast(new Usf500NQueryFlowRateHandler(this,(byte)flowdata.Address,flowdata.Channel)); _lstHandler.AddLast(new Usf500NQueryFlowVolumeHandler(this, (byte)flowdata.Address, flowdata.Channel)); } //_lstHandler.AddLast(new FfuAAFQuerySpeedHandler(this, DeviceAddress, GroupAddress)); } internal void ParseFlowRate(byte address, byte channel, byte[] readOutData) { try { for (int i = 0; i < FlowMeterDataSet.Length; i++) { if (FlowMeterDataSet[i].Address == address && FlowMeterDataSet[i].Channel == channel) { int nValue = 0; for(int j=0;j< readOutData.Length;j++) { nValue += readOutData[j] << (8* (readOutData.Length-j-1)); } FlowMeterDataSet[i].FlowRate = nValue; } } } catch(Exception ex) { LOG.Write(ex); } } internal void ParseFlowVolume(byte address, byte channel, byte[] readOutData) { try { for (int i = 0; i < FlowMeterDataSet.Length; i++) { if (FlowMeterDataSet[i].Address == address && FlowMeterDataSet[i].Channel == channel) { int nValue = 0; for (int j = 0; j < readOutData.Length; j++) { nValue += readOutData[j] << (8 * (readOutData.Length - j - 1)); } FlowMeterDataSet[i].TotalFlowVolume = nValue; } } } catch (Exception ex) { LOG.Write(ex); } } public bool Initialize() { //DATA.Subscribe($"{Module}.{Name}.Power", () => _power); //DATA.Subscribe($"{Module}.{Name}.ErrorCode", () => _errorCode); //DATA.Subscribe($"{Module}.{Name}.IsAtSpeed", () => _isAtSpeed); //DATA.Subscribe($"{Module}.{Name}.IsAccelerate", () => _isAccelerate); DATA.Subscribe($"{Name}.DeviceAddress", () => DeviceAddress); DATA.Subscribe($"{Name}.FlowMeterNames", () => GetFlowMeterNames()); if (_connection.Connect()) { EV.PostInfoLog(Module, $"{Module}.{Name} connected"); } _thread = new PeriodicJob(1000, OnTimer, $"{Name} MonitorHandler", true); //DATA.Subscribe($"{Name}.Speed", () => _ffuSpeed); OP.Subscribe($"{Name}.ResetVolume", (cmd, param) => { if (param.Length <1) { EV.PostWarningLog(Module, "Wrong parameter."); return false; } ResetFlowVolumn(param[0].ToString()); EV.PostInfoLog(Module, $"{Name} reset flow volume:{param[0].ToString()}"); return true; }); ConnectionManager.Instance.Subscribe($"{Name}", this); return true; } private List GetFlowMeterNames() { List ret = new List(); if (FlowMeterDataSet == null) return ret; foreach (var flow in FlowMeterDataSet) { ret.Add($"{flow.FlowName},{flow.Address},{flow.Channel},{flow.FlowRate},{flow.TotalFlowVolume}"); } return ret; } public void ResetFlowVolumn(int address, int channel) { lock(_locker) { _lstHandler.AddLast(new Usf500NResetFlowVolumeHandler(this, (byte)address, channel)); } } public void ResetFlowVolumn(string flowName) { foreach(var fdata in FlowMeterDataSet) { if(flowName == fdata.FlowName) { lock (_locker) { _lstHandler.AddLast(new Usf500NResetFlowVolumeHandler(this, (byte)fdata.Address, fdata.Channel)); } } } } private bool OnTimer() { try { _connection.MonitorTimeout(); if (!_connection.IsConnected)// || _connection.IsCommunicationError { lock (_locker) { _lstHandler.Clear(); } //_trigRetryConnect.CLK = !_connection.IsConnected; //if (_trigRetryConnect.Q) //{ // //_connection.SetPortAddress(SC.GetStringValue($"{_scRoot}.{Name}.Address")); // if (!_connection.Connect()) // { // EV.PostAlarmLog(Module, $"Can not connect with {_connection.Address}, {Module}.{Name}"); // } //} return true; } HandlerBase handler = null; if (!_connection.IsBusy) { lock (_locker) { if (_lstHandler.Count == 0 ) { QuerySpeed(); } if (_lstHandler.Count > 0) { handler = _lstHandler.First.Value; _lstHandler.RemoveFirst(); } } if (handler != null) { _connection.Execute(handler); } } return true; } catch (Exception ex) { LOG.Write(ex); } return true; } internal void NoteError() { } public void Monitor() { try { _connection.EnableLog(_enableLog); _trigCommunicationError.CLK = _connection.IsCommunicationError; if (_trigCommunicationError.Q) { EV.PostAlarmLog(Module, $"{Module}.{Name} communication error, {_connection.LastCommunicationError}"); } } catch (Exception ex) { LOG.Write(ex); } } public void Terminate() { try { if (_connection != null) { _connection.Disconnect(); _connection = null; } } catch (Exception ex) { LOG.Write(ex); } } public void Reset() { _connection.SetCommunicationError(false, ""); _trigCommunicationError.RST = true; _trigRetryConnect.RST = true; } } public struct FlowMeterData { public FlowMeterData(string Name,int address,int channel) { FlowName = Name; Address = address; Channel = channel; FlowRate = 0; TotalFlowVolume = 0; } public string FlowName { get; set; } public int Address { get; } public int Channel { get; } public int FlowRate { get; set; } public int TotalFlowVolume { get; set; } } }