Ejemplo n.º 1
0
        public static (EtherCATInfoDescriptionsDevice device, EtherCATInfoDescriptionsGroup group) FindEsi(string esiSourceDirectoryPath, uint manufacturer, uint productCode, uint revision)
        {
            EtherCATInfoDescriptionsDevice device;
            EtherCATInfoDescriptionsGroup  group;

            // try to find ESI in cache
            (_, device, group) = EsiUtilities.TryFindDevice(EsiUtilities.CacheEtherCatInfoSet, manufacturer, productCode, revision);

            if (device == null)
            {
                // update cache
                EsiUtilities.UpdateCache(esiSourceDirectoryPath, manufacturer, productCode, revision);

                // try to find ESI in cache again
                (_, device, group) = EsiUtilities.TryFindDevice(EsiUtilities.CacheEtherCatInfoSet, manufacturer, productCode, revision);

                // it finally failed
                if (device == null)
                {
                    throw new Exception($"Could not find ESI information of manufacturer '0x{manufacturer:X}' for slave with product code '0x{productCode:X}' and revision '0x{revision:X}'.");
                }
            }

            return(device, group);
        }
Ejemplo n.º 2
0
        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);
        }
Ejemplo n.º 3
0
        static EsiUtilities()
        {
            _lock = new object();
            _cacheDirectoryPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "EtherCAT.NET", "Cache");

            Directory.CreateDirectory(_cacheDirectoryPath);

            EsiUtilities.LoadEsiCache();
            EsiUtilities.SourceEtherCatInfoSet = new List <EtherCATInfo>();
        }
Ejemplo n.º 4
0
        private static void LoadEsiCache()
        {
            var infos     = new List <EtherCATInfo>();
            var filePaths = EsiUtilities.EnumerateFiles(_cacheDirectoryPath, ".xml", SearchOption.AllDirectories).ToList();

            foreach (var filePath in filePaths)
            {
                try
                {
                    infos.Add(EsiUtilities.LoadEsi(filePath));
                }
                catch (Exception)
                {
                    // TODO: write warning into logger
                }
            }

            EsiUtilities.CacheEtherCatInfos = infos;
        }
Ejemplo n.º 5
0
        private static void LoadEsiSource(string sourceDirectoryPath)
        {
            List <EtherCATInfo>  infoSet;
            IEnumerable <string> filePathSet;

            infoSet     = new List <EtherCATInfo>();
            filePathSet = EsiUtilities.EnumerateFiles(sourceDirectoryPath, ".xml", SearchOption.AllDirectories);

            foreach (var filePath in filePathSet)
            {
                try
                {
                    infoSet.Add(EsiUtilities.LoadEsi(filePath));
                }
                catch (Exception)
                {
                    // TODO: write warning into logger
                }
            }

            EsiUtilities.SourceEtherCatInfoSet = infoSet;
        }
Ejemplo n.º 6
0
        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);
        }
Ejemplo n.º 7
0
        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();
            });
        }