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 { #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 内部变量 /// /// do--Modbus设备字典(key-DO名称,value-Modbus设备) /// private Dictionary _ioModbusDictionary = new Dictionary(); /// /// 索引DI名称字典(key-DI索引,value-DI名称) /// private Dictionary _indexDIDictionary = new Dictionary(); /// /// 索引DO名称字典(key-DI索引,value-DO名称) /// private Dictionary _indexDODictionary = new Dictionary(); /// /// 索引AI名称字典(key-DI索引,value-AI名称) /// private Dictionary _indexAIDictionary = new Dictionary(); /// /// 索引AO名称字典(key-DI索引,value-AO名称) /// private Dictionary _indexAODictionary = new Dictionary(); /// /// 模块DI字典(key-模块,value-DI名称集合) /// private Dictionary> _moduleDINameListDictionary = new Dictionary>(); /// /// 模块DO字典(key-模块,value-DO名称集合) /// private Dictionary> _moduleDONameListDictionary = new Dictionary>(); /// /// DO-模块字典(key-DO名称,value-模块名称) /// private Dictionary _doModuleDictionary = new Dictionary(); /// /// 模块AI字典(key-模块,value-AI名称集合) /// private Dictionary> _moduleAIListDictionary = new Dictionary>(); /// /// 模块AO字典(key-模块,value-AO名称集合) /// private Dictionary> _moduleAOListDictionary = new Dictionary>(); /// /// DI字典(key-DI名称,value-DI对象) /// private Dictionary _moduleNameDIDictionary = new Dictionary(); /// /// DO字典(key-DO名称,value-DO对象) /// private Dictionary _moduleNameDODictionary = new Dictionary(); /// /// AI字典(key-AI名称,value-AI对象) /// private Dictionary _moduleNameAIDictionary = new Dictionary(); /// /// AO字典(key-AO名称,value-AO对象) /// private Dictionary _moduleNameAODictionary = new Dictionary(); /// /// 模块名称数值字典(key-模块名称,value-数值) /// private ConcurrentDictionary _moduleNameValueDictionary = new ConcurrentDictionary(); /// /// 转换器 /// private IByteTransform byteTransform = new BigEndianByteTransformBase(); #endregion /// /// 初始化 /// public void Initialize(List lst) { bool isSimulate = SC.GetValue("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(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_GALIL, "Galil", "Load galil xml failed"); } } /// /// 初始化设备 /// /// private void InitializeWagoDeviceConfig(WagoDeviceConfig deviceConfig,WagoModbusDevice modbusDevice,List lst) { //DI ushort diStartAddress = (ushort)deviceConfig.WagoDigIn.WagoDIGroups[0].WagoDIs[0].Address; List diLst = new List(); 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++; } } ushort diCount = (ushort)index; _moduleDINameListDictionary[deviceConfig.Module] = diLst; //DO ushort doStartAddress = (ushort)deviceConfig.WagoDigOut.WagoDOGroups[0].WagoDOs[0].Address; List doList = new List(); 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; ushort doCount = (ushort)index; //AI ushort aiStartAddress = (ushort)deviceConfig.WagoAnoIn.WagoAIGroups[0].WagoAIs[0].Address; index = 0; List aiLst = new List(); 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; ushort aiCount = (ushort)index; //AO ushort aoStartAddress = (ushort)deviceConfig.WagoAnoOut.WagoAOGroups[0].WagoAOs[0].Address; index = 0; List aoList = new List(); 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); } } ushort aoCount = (ushort)index; _moduleAOListDictionary[deviceConfig.Module] = aoList; modbusDevice.Initialize(diCount, diStartAddress, doCount, doStartAddress, aiCount, aiStartAddress, aoCount, aoStartAddress); } /// /// 更新DI数组 /// /// /// public void UpdateWagoDIData(string name, bool[] datas) { if (_moduleDINameListDictionary.ContainsKey(name)) { UpdateWagoDIData(_moduleDINameListDictionary[name], datas); } } /// /// 更新Wago DI数字数值 /// /// /// /// private void UpdateWagoDIData(List 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); } } } } /// /// 更新DO数组 /// /// /// public void UpdateWagoDOData(string name, bool[] datas) { if (_moduleDONameListDictionary.ContainsKey(name)) { UpdateWagoDOData(_moduleDONameListDictionary[name], datas); } } /// /// 更新Wago数字数值 /// /// /// /// private void UpdateWagoDOData(List lst,bool[] datas) { for(int i=0;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); } } } } /// /// Digtal IO更新数值 /// /// /// /// private void DigitalIOUpdateValue(string item,bool invert,bool value) { if (invert) { IOModuleManager.Instance.UpdateIoValue(item, !value); } else { IOModuleManager.Instance.UpdateIoValue(item, value); } } /// /// 更新AI数组 /// /// /// public void UpdateWagoAIData(string name, byte[] datas) { if (_moduleAIListDictionary.ContainsKey(name)) { List 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); } } } /// /// 更新AO数组 /// /// /// public void UpdateWagoAOData(string name, byte[] datas) { if (_moduleAOListDictionary.ContainsKey(name)) { List 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); } } } /// /// 更新模拟量数据 /// /// /// /// /// /// 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); } } } /// /// 写入IO数值 /// /// /// /// 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; } } /// /// 设置DO数值 /// /// /// /// 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; } } /// /// 设置AO数值 /// /// /// /// 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 = BitConverter.GetBytes((short)var.Item2); } else { writeByts = BitConverter.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; } } } }