123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345 |
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Windows.Forms.VisualStyles;
- using Aitex.Core.RT.Log;
- using Aitex.Core.RT.PLC;
- using Aitex.Core.Util;
- namespace Aitex.Core.RT.IOCore
- {
- public class IOGroupManager
- {
- public const int DioBlockLength = 200;
- public const int AioBlockLength = 200;
- private Dictionary<string, IO_DEFINE> _ioDefine = new Dictionary<string, IO_DEFINE>();
- private object _iomapLocker = new object();
- private Dictionary<string, object> _ioMap = new Dictionary<string, object>();
- private Dictionary<string, bool[]> _di = new Dictionary<string, bool[]>();
- private Dictionary<string, bool[]> _do = new Dictionary<string, bool[]>();
- private Dictionary<string, float[]> _ai = new Dictionary<string, float[]>();
- private Dictionary<string, float[]> _ao = new Dictionary<string, float[]>();
- private InterlockManager _interlock = new InterlockManager();
- private PeriodicJob _monitorThread;
- private Dictionary<string, int[]> _dicPlcIoBaseAddress = new Dictionary<string, int[]>();
- public void Initialize(Dictionary<string, string> ioDefineXmlFile, string interlockConfigFile, Dictionary<string, int[]> plcIoBaseAddress, List<string> logicDi)
- {
- _dicPlcIoBaseAddress = plcIoBaseAddress;
- try
- {
- foreach (var item in ioDefineXmlFile)
- {
- if (!File.Exists(item.Value))
- throw new Exception(string.Format("IO item define file not exist, {0}", item.Value));
- _ioDefine[item.Key] = CustomXmlSerializer.Deserialize<IO_DEFINE>(new FileInfo(item.Value));
- _di[item.Key] = new bool[DioBlockLength];
- _do[item.Key] = new bool[DioBlockLength];
- _ai[item.Key] = new float[AioBlockLength];
- _ao[item.Key] = new float[AioBlockLength];
- IOMapping(item.Key, plcIoBaseAddress[item.Key]);
- }
- }
- catch (Exception ex)
- {
- LOG.Write(ex);
- throw new Exception(string.Format("IO define file found error, \r\n {0}", ex.Message));
- }
- _di["logic"] = new bool[DioBlockLength];
- int index = 0;
- foreach (var diName in logicDi)
- {
- DIAccessor diAccessor = new DIAccessor(diName, index, _di["logic"], _di["logic"]);
- _ioMap[diName] = diAccessor;
- diAccessor.IoTableIndex = index;
- index++;
- }
- string reason = string.Empty;
- if (!_interlock.Initialize(interlockConfigFile, _ioMap, out reason))
- {
- throw new Exception(string.Format("interlock define file found error: \r\n {0}", reason));
- }
- _monitorThread = new PeriodicJob(200, OnTimer, "IO Monitor Thread", true);
- }
- private bool OnTimer()
- {
- try
- {
- _interlock.Monitor();
- }
- catch (Exception ex)
- {
- LOG.Write(ex);
- }
- return true;
- }
- public void Update<T, V>(string group, IDataBuffer<T, V> buf)
- where T : struct
- where V : struct
- {
- buf.UpdateDI(_di[group]);
- buf.UpdateDO(_do[group]);
- buf.UpdateAI(_ai[group]);
- buf.UpdateAO(_ao[group]);
- }
- public T GetIO<T>(string name) where T : class
- {
- T obj = null;
- lock (_iomapLocker)
- {
- if (_ioMap.ContainsKey(name))
- obj = _ioMap[name] as T;
- }
- if (obj == null)
- {
- if (!String.IsNullOrWhiteSpace(name))
- LOG.Error(string.Format("IO not match, can not find {0}", name));
- }
- return obj;
- }
- private void IOMapping(string group, int[] plcIoBaseAddress)
- {
- lock (_iomapLocker)
- {
- //DI
- foreach (DI_ITEM item in _ioDefine[group].Dig_In)
- {
- if (string.IsNullOrEmpty(item.Name))
- continue;
- int index = GetIndex(item.Addr, plcIoBaseAddress[0]);
- if (index > 200)
- {
- LOG.Write(String.Format("DI {0} mapping index larger than buffer, addr is {1}", item.Index, item.Addr));
- }
- if (index >= 0)
- {
- DIAccessor diAccessor = new DIAccessor(item.Name, index, _di[group], _di[group]);
- _ioMap[item.Name] = diAccessor;
- diAccessor.IoTableIndex = item.Index;
- //DATA.Subscribe(String.Format("IO.DI.{0}", item.Name), () => { return diAccessor.Value; });
- }
- else
- {
- LOG.Write(String.Format("DI{0} mapping error, addr is {1}", item.Index, item.Addr));
- }
- }
- //DO
- foreach (DO_ITEM item in _ioDefine[group].Dig_Out)
- {
- if (string.IsNullOrEmpty(item.Name))
- continue;
- int index = GetIndex(item.Addr, plcIoBaseAddress[1]);
- if (index > 200)
- {
- LOG.Write(String.Format("DO {0} mapping index larger than buffer, addr is {1}", item.Index, item.Addr));
- }
- if (index >= 0)
- {
- DOAccessor doAccessor = new DOAccessor(item.Name, index, _do[group]);
- _ioMap[item.Name] = doAccessor;
- doAccessor.IoTableIndex = item.Index;
- //DATA.Subscribe(String.Format("IO.DO.{0}", item.Name), () => { return doAccessor.Value; });
- }
- else
- {
- LOG.Write(String.Format("DO{0} mapping error, addr is {1}", item.Index, item.Addr));
- }
- }
- //AI
- foreach (AI_ITEM item in _ioDefine[group].Ana_In)
- {
- if (string.IsNullOrEmpty(item.Name))
- continue;
- int index = GetIndex(item.Addr, plcIoBaseAddress[2]);
- if (index > 200)
- {
- LOG.Write(String.Format("AI {0} mapping index larger than buffer, addr is {1}", item.Index, item.Addr));
- }
- if (index >= 0)
- {
- AIAccessor aiAccessor = new AIAccessor(item.Name, index, _ai[group]);
- _ioMap[item.Name] = aiAccessor;
- aiAccessor.IoTableIndex = item.Index;
- //DATA.Subscribe(String.Format("IO.AI.{0}", item.Name), () => { return aiAccessor.Value; });
- }
- else
- {
- LOG.Write(String.Format("AI{0} mapping error, addr is {1}", item.Index, item.Addr));
- }
- }
- //AO
- foreach (AO_ITEM item in _ioDefine[group].Ana_Out)
- {
- if (string.IsNullOrEmpty(item.Name))
- continue;
- int index = GetIndex(item.Addr, plcIoBaseAddress[3]);
- if (index > 200)
- {
- LOG.Write(String.Format("AO {0} mapping index larger than buffer, addr is {1}", item.Index, item.Addr));
- }
- if (index >= 0)
- {
- AOAccessor aoAccessor = new AOAccessor(item.Name, index, _ao[group]);
- _ioMap[item.Name] = aoAccessor;
- aoAccessor.IoTableIndex = item.Index;
- //DATA.Subscribe(String.Format("IO.AO.{0}", item.Name), () => { return aoAccessor.Value; });
- }
- else
- {
- LOG.Write(String.Format("AO{0} mapping error, addr is {1}", item.Index, item.Addr));
- }
- }
- }
- }
- private int GetIndex(string addr, int first)
- {
- if (String.IsNullOrEmpty(addr))
- {
- LOG.Write("GetIndex addr is empty");
- return -1;
- }
- string[] parts = addr.Trim().ToUpper().Split('.');
- int len = parts.Length;
- if (len == 1)
- {
- string ch = parts[0].TrimStart('D');
- int index = Convert.ToUInt16(ch);
- return (index - first) / 2;
- }
- if (len == 2)
- {
- char[] trim = { 'W', 'C', 'I', 'O', ' ' };
- string ch = parts[0].TrimStart(trim);
- int index = Convert.ToUInt16(ch);
- int bit = Convert.ToUInt16(parts[1]);
- return (index - first) * 16 + bit;
- }
- LOG.Info("IOManager GetIndex error");
- return -1;
- }
- public bool CanSetDo(string doName, bool onOff, out string reason)
- {
- return _interlock.CanSetDo(doName, onOff, out reason);
- }
- public List<Tuple<int, int, string>> GetIONameList(string group, IOType ioType)
- {
- List<Tuple<int, int, string>> result = new List<Tuple<int, int, string>>();
- if (!_dicPlcIoBaseAddress.ContainsKey(group))
- return result;
- int[] plcIoBaseAddress = _dicPlcIoBaseAddress[group];
- switch (ioType)
- {
- case IOType.AI:
- foreach (AI_ITEM item in _ioDefine[group].Ana_In)
- {
- if (string.IsNullOrEmpty(item.Name))
- continue;
- result.Add(Tuple.Create(item.Index, GetIndex(item.Addr, plcIoBaseAddress[2]), item.Name));
- }
- break;
- case IOType.AO:
- foreach (AO_ITEM item in _ioDefine[group].Ana_Out)
- {
- if (string.IsNullOrEmpty(item.Name))
- continue;
- result.Add(Tuple.Create(item.Index, GetIndex(item.Addr, plcIoBaseAddress[3]), item.Name));
- }
- break;
- case IOType.DI:
- foreach (DI_ITEM item in _ioDefine[group].Dig_In)
- {
- if (string.IsNullOrEmpty(item.Name))
- continue;
- result.Add(Tuple.Create(item.Index, GetIndex(item.Addr, plcIoBaseAddress[0]), item.Name));
- }
- break;
- case IOType.DO:
- foreach (DO_ITEM item in _ioDefine[group].Dig_Out)
- {
- if (string.IsNullOrEmpty(item.Name))
- continue;
- result.Add(Tuple.Create(item.Index, GetIndex(item.Addr, plcIoBaseAddress[1]), item.Name));
- }
- break;
- }
- return result;
- }
- public void Terminate()
- {
- try
- {
- _monitorThread.Stop();
- }
- catch (Exception ex)
- {
- LOG.Write(ex);
- }
- }
- }
- }
|