123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- using Aitex.Core.RT.Device;
- using Aitex.Core.RT.Event;
- using Aitex.Core.RT.Log;
- using Aitex.Core.RT.SCCore;
- using Aitex.Core.Util;
- using MECF.Framework.Common.Communications;
- using MECF.Framework.Common.Device.Bases;
- using MECF.Framework.Common.Equipment;
- using System;
- using System.Collections.Generic;
- using System.IO.Ports;
- using System.Linq;
- using System.Threading;
- namespace MECF.Framework.RT.EquipmentLibrary.HardwareUnits.MFCs.HoribaMFC
- {
- public class HoribaMessage : BinaryMessage
- {
- public string DeviceAddress { get; set; }
- public string Action { get; set; }
- public string Parameter { get; set; }
- public int DataLength { get; set; }
- public string ErrorText { get; set; }
- public byte[] Datas { get; set; }
- }
- public class HoribaConnection : SerialPortConnectionBase
- {
- private const int STX = 0x02;
- private const int ETX = 0x03;
- private const int NAK = 0x15;
- private List<byte> _lstCacheBuffer = new List<byte>();
- private PeriodicJob _thread;
- private bool _activeMonitorStatus;
- private R_TRIG _trigWarningMessage = new R_TRIG();
- private R_TRIG _trigCommunicationError = new R_TRIG();
- private R_TRIG _trigRetryConnect = new R_TRIG();
- private LinkedList<HandlerBase> _lstHandler = new LinkedList<HandlerBase>();
- private object _locker = new object();
- private bool _enableLog = true;
- private bool _isFirstTime = true;
- private int _reconnectCount = 0;
- private DeviceTimer _QueryScaleTimer = new DeviceTimer();
- private readonly int _QueryScaleInterval = 3000;
- private List<MfcBase> MFCList = new List<MfcBase>();
- private Dictionary<string, string> _slaveAddress = new Dictionary<string, string>();
- public event Action<string, float> OnFlowReadout; // address, data
- public event Action<string, string> OnUnitReadout; // address, unit
- private string _scRoot;
- public HoribaConnection(string module, string name, string scRoot) : base(SC.GetStringValue($"{scRoot}.Address"), 38400, 7, Parity.Odd, StopBits.One, "\r", false)
- {
- _activeMonitorStatus = true;
- Module = module;
- Name = name;
- _scRoot = scRoot;
- _enableLog = SC.GetValue<bool>($"{_scRoot}.EnableLogMessage");
- EnableLog(_enableLog);
- if (Connect())
- {
- EV.PostInfoLog(Module, $"{Module}.{Name} connected");
- }
- Thread.Sleep(2000);
- if (SC.ContainsItem("System.IsSimulatorMode") && SC.GetValue<bool>("System.IsSimulatorMode"))
- _thread = new PeriodicJob(200, OnTimer, $"{Module}.{Name} MonitorHandler", true);
- else
- _thread = new PeriodicJob(100, OnTimer, $"{Module}.{Name} MonitorHandler", true);
- }
- public string Module { get; set; }
- public string Name { get; set; }
- private bool OnTimer()
- {
- try
- {
- MonitorTimeout();
- if (!IsConnected || IsCommunicationError)
- {
- _trigRetryConnect.CLK = !IsConnected;
- if (_trigRetryConnect.Q)
- {
- EV.PostAlarmLog(Module, $"Disconnect with {Module}.{Name} {SC.GetStringValue($"{_scRoot}.Address")}");
- _reconnectCount = 0;
- }
- if (_reconnectCount <= SC.GetValue<int>($"{_scRoot}.ReconnectCount"))
- {
- //SetPortAddress(SC.GetStringValue($"{Module}.MFCSerialPortName"));
- Connect();
- Thread.Sleep(2000);
- if (IsConnected)
- {
- Reset();
- EV.PostInfoLog(Module, $"Reconnect with {Module}.{Name} {SC.GetStringValue($"{_scRoot}.Address")} successed");
- }
- else
- {
- EV.PostWarningLog(Module, $"Can not connect with {Module}.{Name} {SC.GetStringValue($"{_scRoot}.Address")}, retry {_reconnectCount}");
- Thread.Sleep(1000);
- }
- }
- lock (_locker)
- {
- _lstHandler.Clear();
- _reconnectCount++;
- }
- return true;
- }
- HandlerBase handler = null;
- if (!IsBusy)
- {
- lock (_locker)
- {
- if (_lstHandler.Count == 0 && _activeMonitorStatus)
- {
- foreach (var key in _slaveAddress.Keys)
- {
- _lstHandler.AddLast(new HoribaMFCQueryFlow(this, _slaveAddress[key]));
- if (_QueryScaleTimer.IsTimeout())
- _lstHandler.AddLast(new HoribaMFCQueryScale(this, _slaveAddress[key]));
- if (_isFirstTime)
- {
- _lstHandler.AddLast(new HoribaMFCQueryScale(this, _slaveAddress[key]));
- _lstHandler.AddLast(new HoribaMFCSetDigitalMode(this, _slaveAddress[key]));
- }
- }
- if (_QueryScaleTimer.IsTimeout())
- _QueryScaleTimer.Start(_QueryScaleInterval);
- _isFirstTime = false;
- }
- if (_lstHandler.Count > 0)
- {
- handler = _lstHandler.First.Value;
- _lstHandler.RemoveFirst();
- }
- }
- if (handler != null)
- {
- Execute(handler);
- }
- }
- EnableLog(_enableLog);
- _trigCommunicationError.CLK = IsCommunicationError;
- if (_trigCommunicationError.Q)
- {
- EV.PostAlarmLog(Module, $"{Module}.{Name} communication error");
- }
- }
- catch (Exception ex)
- {
- LOG.Write(ex);
- }
- return true;
- }
- public void AddHandler(HandlerBase handler)
- {
- lock (_locker)
- {
- _lstHandler.AddLast(handler);
- }
- }
- public void AddMFC(MfcBase mfc)
- {
- MFCList.Add(mfc);
- }
- public void AddSlaveAddress(string name, string address)
- {
- _slaveAddress.Add(name, address.PadLeft(2, '0'));
- }
- public void SetFlow(string address, float flow)
- {
- lock (_locker)
- {
- _lstHandler.AddLast(new HoribaMFCSetFlow(this, address, flow));
- }
- }
- public void NoteFlowReadout(string address, float flow)
- {
- if (OnFlowReadout != null)
- OnFlowReadout(address, flow);
- }
- public void NoteUnitReadout(string address, string unit)
- {
- if (OnUnitReadout != null)
- OnUnitReadout(address, unit);
- }
- public void Reset()
- {
- _trigWarningMessage.RST = true;
- SetCommunicationError(false, "");
- _trigCommunicationError.RST = true;
- _enableLog = SC.GetValue<bool>($"{_scRoot}.EnableLogMessage");
- _trigRetryConnect.RST = true;
- _reconnectCount = 0;
- }
- public override bool SendMessage(byte[] message)
- {
- _lstCacheBuffer.Clear();
- return base.SendMessage(message);
- }
- public void Terminate()
- {
- }
- public void SetError(byte[] content)
- {
- string reason = System.Text.Encoding.ASCII.GetString(content);
- _trigWarningMessage.CLK = true;
- if (_trigWarningMessage.Q)
- {
- EV.PostWarningLog(Module, $"{Module}.{Name} error, {reason}");
- }
- }
- protected override MessageBase ParseResponse(byte[] rawMessage)
- {
- _lstCacheBuffer.AddRange(rawMessage);
- byte[] temps = _lstCacheBuffer.ToArray();
- HoribaMessage msg = new HoribaMessage();
- msg.IsResponse = false;
- msg.IsAck = false;
- msg.IsComplete = false;
- msg.RawMessage = _lstCacheBuffer.ToArray();
- if (_lstCacheBuffer.Count < 4 || _lstCacheBuffer[_lstCacheBuffer.Count - 2] != ETX)
- return msg;
- if (temps.Length > 0 && (int)temps[0] == NAK)
- {
- LOG.Error($"NAK, " + temps);
- msg.IsNak = true;
- return msg;
- }
- if (temps.Length < 4)
- {
- LOG.Error($"text length check failed");
- msg.IsFormatError = true;
- return msg;
- }
- if ((int)temps[0] != STX)
- {
- LOG.Error($"text check STX failed");
- msg.IsFormatError = true;
- return msg;
- }
- int etxIndex = 0;
- foreach (var item in temps)
- {
- if ((int)item == ETX)
- break;
- etxIndex++;
- }
- if (etxIndex >= temps.Length)
- {
- LOG.Error($"text check ETX failed");
- msg.IsFormatError = true;
- return msg;
- }
- msg.DataLength = etxIndex - 1;
- msg.Datas = new byte[etxIndex - 1];
- ///STX msg ETX BCC
- Array.Copy(temps, 1, msg.Datas, 0, etxIndex - 1);
- var bcc = (int)temps[etxIndex + 1];
- int checkBCC = 0;
- foreach (var item in msg.Datas)
- {
- checkBCC += (int)item;
- }
- checkBCC += ETX;
- if (checkBCC % 128 != bcc)
- {
- LOG.Error($"check BCC failed");
- msg.IsFormatError = true;
- return msg;
- }
- msg.IsResponse = true;
- msg.IsAck = true;
- msg.IsComplete = true;
- return msg;
- }
- }
- }
|