| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573 | using Aitex.Common.Util;using Aitex.Core.RT.Log;using Aitex.Core.RT.SCCore;using Aitex.Core.Util;using DocumentFormat.OpenXml.Wordprocessing;using MECF.Framework.Common.Device.Festo;using MECF.Framework.Common.Equipment;using MECF.Framework.Common.IOCore;using MECF.Framework.Common.Net;using MECF.Framework.Common.TwinCat;using System;using System.Collections.Concurrent;using System.Collections.Generic;using System.IO;using System.Linq;using System.Reflection;using System.Text;using System.Threading.Tasks;using System.Xml.Linq;namespace MECF.Framework.Common.Device.Wago{    public class WagoControllerCfgManager : Singleton<WagoControllerCfgManager>    {        #region 常量         private const string STOPCODE = "StopCode";        private const string REFERENCE_POSITION = "ReferencePosition";        private const string TORQUE = "Torque";        private const string VELOCITY = "Velocity";        private const string POSITION_ERROR = "PositionError";        private const string AUXILIARY_POSITION = "AuxiliaryPosition";        #endregion        #region 内部变量        /// <summary>        /// do--Modbus设备字典(key-DO名称,value-Modbus设备)        /// </summary>        private Dictionary<string, WagoModbusDevice> _ioModbusDictionary = new Dictionary<string, WagoModbusDevice>();        /// <summary>        /// 索引DI名称字典(key-DI索引,value-DI名称)        /// </summary>        private Dictionary<int, string> _indexDIDictionary = new Dictionary<int, string>();        /// <summary>        /// 索引DO名称字典(key-DI索引,value-DO名称)        /// </summary>        private Dictionary<int, string> _indexDODictionary = new Dictionary<int, string>();        /// <summary>        /// 索引AI名称字典(key-DI索引,value-AI名称)        /// </summary>        private Dictionary<int, string> _indexAIDictionary = new Dictionary<int, string>();        /// <summary>        /// 索引AO名称字典(key-DI索引,value-AO名称)        /// </summary>        private Dictionary<int, string> _indexAODictionary = new Dictionary<int, string>();        /// <summary>        /// 模块DI字典(key-模块,value-DI名称集合)        /// </summary>        private Dictionary<string, List<string>> _moduleDINameListDictionary = new Dictionary<string, List<string>>();        /// <summary>        /// 模块DO字典(key-模块,value-DO名称集合)        /// </summary>        private Dictionary<string, List<string>> _moduleDONameListDictionary = new Dictionary<string, List<string>>();        /// <summary>        /// DO-模块字典(key-DO名称,value-模块名称)        /// </summary>        private Dictionary<string, string> _doModuleDictionary = new Dictionary<string, string>();        /// <summary>        /// 模块AI字典(key-模块,value-AI名称集合)        /// </summary>        private Dictionary<string, List<WagoAI>> _moduleAIListDictionary = new Dictionary<string, List<WagoAI>>();        /// <summary>        /// 模块AO字典(key-模块,value-AO名称集合)        /// </summary>        private Dictionary<string, List<WagoAO>> _moduleAOListDictionary = new Dictionary<string, List<WagoAO>>();        /// <summary>        /// DI字典(key-DI名称,value-DI对象)        /// </summary>        private Dictionary<string, WagoDI> _moduleNameDIDictionary = new Dictionary<string, WagoDI>();        /// <summary>        /// DO字典(key-DO名称,value-DO对象)        /// </summary>        private Dictionary<string,WagoDO> _moduleNameDODictionary = new Dictionary<string, WagoDO>();        /// <summary>        /// AI字典(key-AI名称,value-AI对象)        /// </summary>        private Dictionary<string, WagoAI> _moduleNameAIDictionary = new Dictionary<string, WagoAI>();        /// <summary>        /// AO字典(key-AO名称,value-AO对象)        /// </summary>        private Dictionary<string, WagoAO> _moduleNameAODictionary = new Dictionary<string, WagoAO>();        /// <summary>        /// 模块名称数值字典(key-模块名称,value-数值)        /// </summary>        private ConcurrentDictionary<string, object> _moduleNameValueDictionary = new ConcurrentDictionary<string, object>();        /// <summary>        /// 转换器        /// </summary>        private IByteTransform byteTransform = new BigEndianByteTransformBase();        #endregion        /// <summary>        /// 初始化        /// </summary>        public void Initialize(List<string> lst)        {            bool isSimulate = SC.GetValue<bool>("System.IsSimulatorMode");            string xmlPath = "";            try            {                if (isSimulate)                {                    xmlPath = PathManager.GetCfgDir() + "Devices\\WagoControllerCfg-Simulator.xml";                }                else                {                    xmlPath = PathManager.GetCfgDir() + "Devices\\WagoControllerCfg.xml";                }                WagoControllerCfg cfg = CustomXmlSerializer.Deserialize<WagoControllerCfg>(new FileInfo(xmlPath));                if (cfg != null)                {                    foreach (var config in cfg.WagoDeviceConfigs)                    {                        WagoModbusDevice modbusDevice = new WagoModbusDevice(config.Module, config.IpAddress, config.Port,                            (byte)config.Channel);                        modbusDevice.ReceiveTimeout = config.RecvTimeout;                        modbusDevice.SendTimeout = config.SendTimeout;                        InitializeWagoDeviceConfig(config, modbusDevice, lst);                    }                }            }            catch            {                LOG.WriteLog(eEvent.ERR_WAGO, "wago", "Load galil xml failed");            }        }        /// <summary>        /// 初始化设备        /// </summary>        /// <param name="deviceConfig"></param>        private void InitializeWagoDeviceConfig(WagoDeviceConfig deviceConfig,WagoModbusDevice modbusDevice,List<string> lst)        {            //DI            ushort diStartAddress = 0;            ushort diCount = 0;            if (deviceConfig.WagoDigIn != null &&  deviceConfig.WagoDigIn.WagoDIGroups?.Count != 0)            {                diStartAddress = (ushort)deviceConfig.WagoDigIn.WagoDIGroups[0].WagoDIs[0].Address;                List<string> diLst = new List<string>();                int index = 0;                foreach (var group in deviceConfig.WagoDigIn.WagoDIGroups)                {                    foreach (var item in group.WagoDIs)                    {                        _indexDIDictionary[index] = item.Name;                        _moduleNameDIDictionary[item.Name] = item;                        diLst.Add(item.Name);                        lst.Add(item.Name);                        index++;                    }                }                diCount = (ushort)index;                _moduleDINameListDictionary[deviceConfig.Module] = diLst;            }            //DO            ushort doStartAddress = 0;            ushort doCount = 0;            if (deviceConfig.WagoDigOut != null && deviceConfig.WagoDigOut.WagoDOGroups?.Count != 0)            {                doStartAddress = (ushort)deviceConfig.WagoDigOut.WagoDOGroups[0].WagoDOs[0].Address;                List<string> doList = new List<string>();                int index = 0;                foreach (var group in deviceConfig.WagoDigOut.WagoDOGroups)                {                    foreach (WagoDO item in group.WagoDOs)                    {                        _ioModbusDictionary[item.Name] = modbusDevice;                        _indexDODictionary[index] = item.Name;                        doList.Add(item.Name);                        _moduleNameDODictionary[item.Name] = item;                        _doModuleDictionary[item.Name] = deviceConfig.Module;                        lst.Add(item.Name);                        index++;                    }                }                _moduleDONameListDictionary[deviceConfig.Module] = doList;                doCount = (ushort)index;            }            //AI            ushort aiCount = 0;            ushort aiStartAddress = 0;            if ( deviceConfig.WagoAnoIn != null && deviceConfig.WagoAnoIn.WagoAIGroups?.Count != 0)            {                aiStartAddress = (ushort)deviceConfig.WagoAnoIn.WagoAIGroups[0].WagoAIs[0].Address;                int index = 0;                List<WagoAI> aiLst = new List<WagoAI>();                foreach (var group in deviceConfig.WagoAnoIn.WagoAIGroups)                {                    foreach (var item in group.WagoAIs)                    {                        _indexAIDictionary[index] = item.Name;                        if (!string.IsNullOrEmpty(item.Scaling))                        {                            ScalingManager.Instance.Initialize(item.Name, item.Scaling);                        }                        lst.Add(item.Name);                        _moduleNameAIDictionary[item.Name] = item;                        aiLst.Add(item);                        index++;                    }                }                _moduleAIListDictionary[deviceConfig.Module] = aiLst;                aiCount = (ushort)index;            }            //AO            ushort aoStartAddress = 0;            ushort aoCount = 0;            if (deviceConfig.WagoAnoOut!= null && deviceConfig.WagoAnoOut.WagoAOGroups?.Count != 0)            {                aoStartAddress = (ushort)deviceConfig.WagoAnoOut.WagoAOGroups[0].WagoAOs[0].Address;                int index = 0;                List<WagoAO> aoList = new List<WagoAO>();                foreach (var group in deviceConfig.WagoAnoOut.WagoAOGroups)                {                    foreach (var item in group.WagoAOs)                    {                        _ioModbusDictionary[item.Name] = modbusDevice;                        _indexAODictionary[index] = item.Name;                        if (!string.IsNullOrEmpty(item.Scaling))                        {                            ScalingManager.Instance.Initialize(item.Name, item.Scaling);                        }                        _moduleNameAODictionary[item.Name] = item;                        lst.Add(item.Name);                        index++;                        aoList.Add(item);                    }                }                aoCount = (ushort)index;                _moduleAOListDictionary[deviceConfig.Module] = aoList;            }            modbusDevice.Initialize(diCount, diStartAddress, doCount, doStartAddress, aiCount, aiStartAddress, aoCount, aoStartAddress);        }        /// <summary>        /// 更新DI数组        /// </summary>        /// <param name="name"></param>        /// <param name="datas"></param>        public void UpdateWagoDIData(string name, bool[] datas)        {            if (_moduleDINameListDictionary.ContainsKey(name))            {                UpdateWagoDIData(_moduleDINameListDictionary[name], datas);            }        }        /// <summary>        /// 更新Wago DI数字数值        /// </summary>        /// <param name="lst"></param>        /// <param name="dic"></param>        /// <param name="datas"></param>        private void UpdateWagoDIData(List<string> lst, bool[] datas)        {            for (int i = 0; i < lst.Count; i++)            {                string item = lst[i];                if (i >= datas.Length)                {                    continue;                }                if (!_moduleNameDIDictionary.ContainsKey(item))                {                    continue;                }                WagoDI wagoDI = _moduleNameDIDictionary[item];                bool value = datas[i];                if (!_moduleNameValueDictionary.ContainsKey(item))                {                    _moduleNameValueDictionary[item] = value;                    DigitalIOUpdateValue(item, wagoDI.Invert, value);                }                else                {                    if (value != (bool)_moduleNameValueDictionary[item])                    {                        _moduleNameValueDictionary[item] = value;                        DigitalIOUpdateValue(item, wagoDI.Invert, value);                    }                }            }        }        /// <summary>        /// 更新DO数组        /// </summary>        /// <param name="name"></param>        /// <param name="datas"></param>        public void UpdateWagoDOData(string name, bool[] datas)        {            if (_moduleDONameListDictionary.ContainsKey(name))            {                UpdateWagoDOData(_moduleDONameListDictionary[name], datas);            }        }        /// <summary>        /// 更新Wago数字数值        /// </summary>        /// <param name="lst"></param>        /// <param name="dic"></param>        /// <param name="datas"></param>        private void UpdateWagoDOData(List<string> lst,bool[] datas)        {            for(int i=0;i<lst.Count;i++)            {                                string item=lst[i];                if (i >= datas.Length)                {                    continue;                }                if (!_moduleNameDODictionary.ContainsKey(item))                {                    continue;                }                WagoDO wagoDO=_moduleNameDODictionary[item];                bool value = datas[i];                if (!_moduleNameValueDictionary.ContainsKey(item))                {                    _moduleNameValueDictionary[item] = value;                    DigitalIOUpdateValue(item, wagoDO.Invert, value);                }                else                {                    if (value != (bool)_moduleNameValueDictionary[item])                    {                        _moduleNameValueDictionary[item] = value;                        DigitalIOUpdateValue(item, wagoDO.Invert, value);                    }                }            }        }        /// <summary>        /// Digtal IO更新数值        /// </summary>        /// <param name="item"></param>        /// <param name="invert"></param>        /// <param name="value"></param>        private void DigitalIOUpdateValue(string item,bool invert,bool value)        {            if (invert)            {                IOModuleManager.Instance.UpdateIoValue(item, !value);            }            else            {                IOModuleManager.Instance.UpdateIoValue(item, value);            }        }        /// <summary>        /// 更新AI数组        /// </summary>        /// <param name="name"></param>        /// <param name="datas"></param>        public void UpdateWagoAIData(string name, byte[] datas)        {            if (_moduleAIListDictionary.ContainsKey(name))            {                List<WagoAI> wagoAIs = _moduleAIListDictionary[name];                for(int i = 0; i < wagoAIs.Count; i++)                {                    WagoAI wagoAI = wagoAIs[i];                    if (i * 2 >= datas.Length)                    {                        break;                    }                    UpdateWagoAnalogData(wagoAI.Name, wagoAI.Scaling, wagoAI.DataType, datas, i);                }            }        }        /// <summary>        /// 更新AO数组        /// </summary>        /// <param name="name"></param>        /// <param name="datas"></param>        public void UpdateWagoAOData(string name, byte[] datas)        {            if (_moduleAOListDictionary.ContainsKey(name))            {                List<WagoAO> wagoAOs = _moduleAOListDictionary[name];                for (int i = 0; i < wagoAOs.Count; i++)                {                    WagoAO wagoAO = wagoAOs[i];                    if (i * 2 >= datas.Length)                    {                        break;                    }                    UpdateWagoAnalogData(wagoAO.Name, wagoAO.Scaling, wagoAO.DataType, datas, i);                }            }        }        /// <summary>        /// 更新模拟量数据        /// </summary>        /// <param name="moduleName"></param>        /// <param name="scaling"></param>        /// <param name="dataType"></param>        /// <param name="datas"></param>        /// <param name="index"></param>        private void UpdateWagoAnalogData(string moduleName,string scaling,string dataType, byte[] datas,int index)        {            object value = null;            if (dataType == "short")            {                value = byteTransform.TransInt16(datas, index * 2);            }            else            {                value = byteTransform.TransUInt16(datas, index * 2);            }            if (!string.IsNullOrEmpty(scaling))            {                var result = ScalingManager.Instance.CalculateValueByTwincatVariable(moduleName, double.Parse(value.ToString()));                if (result.Item1)                {                    value = result.Item2;                }                else                {                    return;                }            }            if (!_moduleNameValueDictionary.ContainsKey(moduleName))            {                _moduleNameValueDictionary[moduleName] = value;                IOModuleManager.Instance.UpdateIoValue(moduleName, value);            }            else            {                if (value.ToString() != _moduleNameValueDictionary[moduleName].ToString())                {                    _moduleNameValueDictionary[moduleName] = value;                    IOModuleManager.Instance.UpdateIoValue(moduleName, value);                }            }        }        /// <summary>        /// 写入IO数值        /// </summary>        /// <param name="ioName"></param>        /// <param name="value"></param>        /// <returns></returns>        public bool WriteIOValue(string ioName,object value)        {            if (_moduleNameDODictionary.ContainsKey(ioName))            {                return SetDoValue(ioName, (bool)value);            }            else if (_moduleNameAODictionary.ContainsKey(ioName))            {                return SetAoValue(ioName, (double)value);            }            else            {                LOG.WriteLog(eEvent.ERR_WAGO, "Wago", $"{ioName} object is null");                return false;            }        }        /// <summary>        /// 设置DO数值        /// </summary>        /// <param name="doName"></param>        /// <param name="value"></param>        /// <returns></returns>        private bool SetDoValue(string doName, bool value)        {            if (!_moduleNameDODictionary.ContainsKey(doName))            {                LOG.WriteLog(eEvent.ERR_WAGO, "Wago", $"{doName} object is null");                return false;            }            WagoDO wagoDO = _moduleNameDODictionary[doName];            if (!_ioModbusDictionary.ContainsKey(doName))            {                LOG.WriteLog(eEvent.ERR_WAGO, "Wago", $"{doName} wago device is null");                return false;            }            WagoModbusDevice device = _ioModbusDictionary[doName];            if (!_doModuleDictionary.ContainsKey(doName))            {                LOG.WriteLog(eEvent.ERR_WAGO, "Wago", $"{doName} does not have module dictionary");                return false;            }            string module = _doModuleDictionary[doName];            try            {                bool lastValue = wagoDO.Invert ? !value : value;                byte festoValue = lastValue ? (byte)0xFF : (byte)0x00;                bool result = device.WriteDOValue((ushort)wagoDO.Address, festoValue);                if (result)                {                    LOG.WriteLog(eEvent.INFO_WAGO, "Wago", $"{doName} write {value} success");                }                else                {                    LOG.WriteLog(eEvent.ERR_WAGO, "Wago", $"{doName} write {value} failed");                }                return result;            }            catch (Exception ex)            {                LOG.WriteLog(eEvent.ERR_WAGO, "Wago", $"write {doName} value {value} {ex.Message}");                return false;            }        }        /// <summary>        /// 设置AO数值        /// </summary>        /// <param name="aoName"></param>        /// <param name="value"></param>        /// <returns></returns>        public bool SetAoValue(string aoName, double value)        {            if (!_moduleNameAODictionary.ContainsKey(aoName))            {                LOG.WriteLog(eEvent.ERR_WAGO, "Wago", $"{aoName} object is null");                return false;            }            WagoAO wagoAO = _moduleNameAODictionary[aoName];            if (!_ioModbusDictionary.ContainsKey(aoName))            {                LOG.WriteLog(eEvent.ERR_WAGO, "Wago", $"{aoName} wago device is null");                return false;            }            WagoModbusDevice device = _ioModbusDictionary[aoName];            try            {                byte[] writeByts = null;                if (!string.IsNullOrEmpty(wagoAO.Scaling))                {                    var var=ScalingManager.Instance.CalculateTwincatValueByInput(aoName, value);                    if (var.Item1)                    {                        if (wagoAO.DataType == "short")                        {                            writeByts = byteTransform.GetBytes((short)var.Item2);                        }                        else                        {                            writeByts = byteTransform.GetBytes((ushort)var.Item2);                        }                    }                }                bool result = device.WriteAOValue((ushort)wagoAO.Address, writeByts);                if (result)                {                    LOG.WriteLog(eEvent.INFO_WAGO, "Wago", $"{aoName} write {value} success");                }                else                {                    LOG.WriteLog(eEvent.ERR_WAGO, "Wago", $"{aoName} write {value} failed");                }                return result;            }            catch (Exception ex)            {                LOG.WriteLog(eEvent.ERR_WAGO, "Wago", $"write {aoName} value {value} {ex.Message}");                return false;            }        }    }}
 |