private static bool UpdateCache(string esiSourceDirectoryPath, uint manufacturer, uint productCode, uint revision) { // check if source ESI files have been loaded if (!EsiUtilities.SourceEtherCatInfoSet.Any()) { EsiUtilities.LoadEsiSource(esiSourceDirectoryPath); } // try to find requested device info (var sourceInfo, var sourceDevice, _) = EsiUtilities.TryFindDevice(EsiUtilities.SourceEtherCatInfoSet, manufacturer, productCode, revision); if (sourceDevice == null) { return(false); } lock (_lock) { // find matching EtherCATInfo in cache var cacheInfo = EsiUtilities.CacheEtherCatInfoSet.FirstOrDefault(current => { var vendorId = (uint)EsiUtilities.ParseHexDecString(current.Vendor.Id); return(vendorId == manufacturer); }); // extend cache file if (cacheInfo != null) { // add new groups var cacheGroupSet = cacheInfo.Descriptions.Groups.ToList(); foreach (var sourceGroup in sourceInfo.Descriptions.Groups) { if (!cacheGroupSet.Any(current => current.Type == sourceGroup.Type)) { cacheGroupSet.Add(sourceGroup); } } cacheInfo.Descriptions.Groups = cacheGroupSet.ToArray(); // add found device cacheInfo.Descriptions.Devices = cacheInfo.Descriptions.Devices.ToList().Concat(new[] { sourceDevice }).ToArray(); } // create new cache file else { cacheInfo = sourceInfo; cacheInfo.Descriptions.Devices = new EtherCATInfoDescriptionsDevice[] { sourceDevice }; EsiUtilities.CacheEtherCatInfoSet.Add(cacheInfo); } // save new/updated EtherCATInfo to disk EsiUtilities.SaveEsi(cacheInfo, Path.Combine(_cacheDirectoryPath, $"{cacheInfo.Vendor.Id}.xml")); } // return return(true); }
private static (EtherCATInfo etherCATInfo, EtherCATInfoDescriptionsDevice device, EtherCATInfoDescriptionsGroup group) TryFindDevice(List <EtherCATInfo> etherCATInfoSet, uint manufacturer, uint productCode, uint revision) { EtherCATInfo info; EtherCATInfoDescriptionsDevice device; EtherCATInfoDescriptionsGroup group; info = null; device = null; foreach (var currentInfo in etherCATInfoSet) { var vendorId = (uint)EsiUtilities.ParseHexDecString(currentInfo.Vendor.Id); if (vendorId != manufacturer) { continue; } device = currentInfo.Descriptions.Devices.FirstOrDefault(currentDevice => { var found = !string.IsNullOrWhiteSpace(currentDevice.Type.ProductCode) && !string.IsNullOrWhiteSpace(currentDevice.Type.RevisionNo) && (int)EsiUtilities.ParseHexDecString(currentDevice.Type.ProductCode) == productCode && (int)EsiUtilities.ParseHexDecString(currentDevice.Type.RevisionNo) == revision; if (found) { info = currentInfo; } return(found); }); if (device != null) { break; } } // try to find old revision if (device == null) { etherCATInfoSet.ToList().ForEach(currentInfo => { device = currentInfo.Descriptions.Devices.Where(currentDevice => { var found = !string.IsNullOrWhiteSpace(currentDevice.Type.ProductCode) && !string.IsNullOrWhiteSpace(currentDevice.Type.RevisionNo) && (int)EsiUtilities.ParseHexDecString(currentDevice.Type.ProductCode) == productCode; if (found) { info = currentInfo; } return(found); }).OrderBy(currentDevice => currentDevice.Type.RevisionNo).LastOrDefault(); }); // return without success if (device == null) { return(null, null, null); } } // find group group = info.Descriptions.Groups.FirstOrDefault(currentGroup => currentGroup.Type == device.GroupType); if (group == null) { throw new Exception($"ESI entry for group type '{device}' not found."); } return(info, device, group); }
public static void CreateDynamicData(string esiDirectoryPath, SlaveInfo slave) { // find ESI if (slave.Csa != 0) { (slave.Esi, slave.EsiGroup) = EsiUtilities.FindEsi(esiDirectoryPath, slave.Manufacturer, slave.ProductCode, slave.Revision); } // var pdos = new List <SlavePdo>(); var base64ImageData = new byte[] { }; var name = slave.Esi.Type.Value; var description = slave.Esi.Name.FirstOrDefault()?.Value; if (description.StartsWith(name)) { description = description.Substring(name.Length); } else if (string.IsNullOrWhiteSpace(description)) { description = "no description available"; } // PDOs foreach (DataDirection dataDirection in Enum.GetValues(typeof(DataDirection))) { IEnumerable <PdoType> pdoTypes = null; switch (dataDirection) { case DataDirection.Output: pdoTypes = slave.Esi.RxPdo; break; case DataDirection.Input: pdoTypes = slave.Esi.TxPdo; break; } foreach (var pdoType in pdoTypes) { var osMax = Convert.ToUInt16(pdoType.OSMax); if (osMax == 0) { var pdoName = pdoType.Name.First().Value; var pdoIndex = (ushort)EsiUtilities.ParseHexDecString(pdoType.Index.Value); var syncManager = pdoType.SmSpecified ? pdoType.Sm : -1; var slavePdo = new SlavePdo(slave, pdoName, pdoIndex, osMax, pdoType.Fixed, pdoType.Mandatory, syncManager); pdos.Add(slavePdo); var slaveVariables = pdoType.Entry.Select(x => { var variableIndex = (ushort)EsiUtilities.ParseHexDecString(x.Index.Value); var subIndex = Convert.ToByte(x.SubIndex); //// Improve. What about -1 if SubIndex does not exist? return(new SlaveVariable(slavePdo, x.Name?.FirstOrDefault()?.Value, variableIndex, subIndex, dataDirection, EcUtilities.ParseEtherCatDataType(x.DataType?.Value), (byte)x.BitLen)); }).ToList(); slavePdo.SetVariables(slaveVariables); } else { for (ushort indexOffset = 0; indexOffset <= osMax - 1; indexOffset++) { var pdoName = $"{pdoType.Name.First().Value} [{indexOffset}]"; var pdoIndex = (ushort)((ushort)EsiUtilities.ParseHexDecString(pdoType.Index.Value) + indexOffset); var syncManager = pdoType.SmSpecified ? pdoType.Sm : -1; var indexOffset_Tmp = indexOffset; var slavePdo = new SlavePdo(slave, pdoName, pdoIndex, osMax, pdoType.Fixed, pdoType.Mandatory, syncManager); pdos.Add(slavePdo); var slaveVariables = pdoType.Entry.Select(x => { var variableIndex = (ushort)EsiUtilities.ParseHexDecString(x.Index.Value); var subIndex = (byte)(byte.Parse(x.SubIndex) + indexOffset_Tmp); //// Improve. What about -1 if SubIndex does not exist? return(new SlaveVariable(slavePdo, x.Name.FirstOrDefault()?.Value, variableIndex, subIndex, dataDirection, EcUtilities.ParseEtherCatDataType(x.DataType?.Value), (byte)x.BitLen)); }).ToList(); slavePdo.SetVariables(slaveVariables); } } } } // image data if (slave.EsiGroup.ItemElementName == ItemChoiceType1.ImageData16x14) { base64ImageData = (byte[])slave.EsiGroup.Item; } if (slave.Esi.ItemElementName.ToString() == nameof(ItemChoiceType1.ImageData16x14)) { base64ImageData = (byte[])slave.Esi.Item; } // attach dynamic data slave.DynamicData = new SlaveInfoDynamicData(name, description, pdos, base64ImageData); // add DC extension to extensions if (slave.Esi.Dc is not null && !slave.Extensions.Any(extension => extension.GetType() == typeof(DistributedClocksExtension))) { slave.Extensions.Add(new DistributedClocksExtension(slave)); } // execute extension logic slave.Extensions.ToList().ForEach(extension => { extension.EvaluateSettings(); }); }