123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.IO;
- using Aitex.Core.RT.Log;
- using Aitex.Core.RT.PLC;
- using Aitex.Core.Util;
- using Aitex.Core.RT.DataCenter;
- namespace Aitex.Core.RT.IOCore
- {
- public class IOManager
- {
- private IO_DEFINE _ioDefine;
- private Interlock _interlock = null;
- private Dictionary<string, IOScale> _dicScale = new Dictionary<string,IOScale>();
- /// <summary>
- /// IO Mapping
- /// </summary>
- private object _iomapLocker;
- private Dictionary<string, object> _ioMap;
- private string _interlockFile;
- /// <summary>
- /// IO Memory buffer for Update
- /// </summary>
- #region IOUpdate
- private int len = 200;
- private bool[] _di;
- private bool[] _do;
- private float[] _ai;
- private float[] _ao;
-
- #endregion
-
-
-
- public IOManager()
- {
- _interlock = new Interlock();
- _iomapLocker = new object();
- _ioMap = new Dictionary<string, object>();
- //DI/DO/AI/AO
- _di = new bool[len];
- _do = new bool[len];
- _ai = new float[len];
- _ao = new float[len];
-
- }
- public bool Initialize(string ioDefineXmlFile, string interlockConfigFile)
- {
- try
- {
- _ioDefine = CustomXmlSerializer.Deserialize<IO_DEFINE>(new FileInfo(ioDefineXmlFile));
- }
- catch (Exception ex)
- {
- LOG.Error("IODefine文件格式不对," + ioDefineXmlFile + "," + ex.Message);
- return false;
- }
- IOMapping();
- _interlockFile = interlockConfigFile;
- string reason;
- if (!InitializeInterlock(out reason))
- {
- LOG.Error("Interlock file has error." + reason);
- return false;
- }
-
- return true;
- }
- public bool InitializeInterlock(out string reason)
- {
- List<Tuple<int, int, string>> doMap = GetIONameList(IOType.DO);
- List<Tuple<int, int, string>> diMap = GetIONameList(IOType.DI);
- List<Tuple<DOAccessor, DIAccessor>> list = new List<Tuple<DOAccessor, DIAccessor>>();
- for (int i = 0; i < 1000; i++)
- {
- int idx = _ioDefine.Dig_Out[i].Safe_Feedback_Index;
- if (idx >= 0 && !String.IsNullOrWhiteSpace(_ioDefine.Dig_Out[i].Name))
- {
- list.Add(Tuple.Create(IO.DO[doMap[i].Item3], IO.DI[diMap[idx].Item3]));
- }
- }
- _interlock.InitSafeDO(list);
- return _interlock.Init(_interlockFile, diMap, doMap, out reason);
- }
- public void Terminate()
- {
-
- }
- public void Monitor()
- {
- if (_interlock != null)
- _interlock.Monitor();
- }
-
- //buf中的数据
- /// <summary>
- /// 更新buf中的数据
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <typeparam name="V"></typeparam>
- /// <param name="buf"></param>
- public void Update<T, V>(IDataBuffer<T, V> buf) where T : struct where V : struct
- {
- buf.UpdateDI(_di);
- buf.UpdateDO(_do);
- buf.UpdateAI(_ai);
- buf.UpdateAO(_ao);
- }
- ///
- 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;
- }
-
- /// <summary>
- /// 返回IO的(io define index,name)列表
- ///
- ///
- /// iodefine index
- /// buffer index
- /// iodefine name
- ///
- /// </summary>
- /// <param name="ioType"></param>
- /// <returns></returns>
- public List<Tuple<int, int, string>> GetIONameList(IOType ioType)
- {
- List<Tuple<int, int, string>> result = new List<Tuple<int, int, string>>();
- switch (ioType)
- {
- case IOType.AI:
- foreach (AI_ITEM item in _ioDefine.Ana_In)
- {
- if (string.IsNullOrEmpty(item.Name))
- continue;
- result.Add(Tuple.Create(item.Index, GetIndex(item.Addr, 2000), item.Name));
- }
- break;
- case IOType.AO:
- foreach (AO_ITEM item in _ioDefine.Ana_Out)
- {
- if (string.IsNullOrEmpty(item.Name))
- continue;
- result.Add(Tuple.Create(item.Index, GetIndex(item.Addr, 1000), item.Name));
- }
- break;
- case IOType.DI:
- foreach (DI_ITEM item in _ioDefine.Dig_In)
- {
- if (string.IsNullOrEmpty(item.Name))
- continue;
- result.Add(Tuple.Create(item.Index, GetIndex(item.Addr, 0), item.Name));
- }
- break;
- case IOType.DO:
- foreach (DO_ITEM item in _ioDefine.Dig_Out)
- {
- if (string.IsNullOrEmpty(item.Name))
- continue;
- result.Add(Tuple.Create(item.Index, GetIndex(item.Addr, 0), item.Name));
- }
- break;
- }
- return result;
- }
- private void IOMapping()
- {
- lock (_iomapLocker)
- {
- //DI
- foreach (DI_ITEM item in _ioDefine.Dig_In)
- {
- if (string.IsNullOrEmpty(item.Name))
- continue;
- int index = GetIndex(item.Addr, 0);
- if (index >= 0)
- {
- DIAccessor diAccessor = new DIAccessor(item.Name, index, _di, _di);
- _ioMap[item.Name] = diAccessor;
- //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.Dig_Out)
- {
- if (string.IsNullOrEmpty(item.Name))
- continue;
- int index = GetIndex(item.Addr, 0);
- if (index >= 0)
- {
- DOAccessor doAccessor = new DOAccessor(item.Name, index, _do);
- _ioMap[item.Name] = doAccessor;
- //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.Ana_In)
- {
- if (string.IsNullOrEmpty(item.Name))
- continue;
- int index = GetIndex(item.Addr, 2000);
- if (index >= 0)
- {
- AIAccessor aiAccessor = new AIAccessor(item.Name, index, _ai);
- _ioMap[item.Name] = aiAccessor;
- //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.Ana_Out)
- {
- if (string.IsNullOrEmpty(item.Name))
- continue;
- int index = GetIndex(item.Addr, 1000);
- if (index >= 0)
- {
- AOAccessor aoAccessor = new AOAccessor(item.Name, index, _ao);
- _ioMap[item.Name] = aoAccessor;
- //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));
- }
- }
-
- }
- }
-
- public bool CanSetDo(string doName, bool onOff, out string reason)
- {
- return _interlock.CanSetDo(doName, onOff, out reason);
- }
- public void SetScale(string ioName, double logicalMin, double logicalMax, double physicalMin, double physicalMax)
- {
- _dicScale[ioName] = new IOScale(ioName, logicalMin, logicalMax, physicalMin, physicalMax);
- }
- public Dictionary<string, IOScale> GetScale()
- {
- return _dicScale;
- }
- 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;
- }
- }
- }
|