/// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="parent">TagGroup对象</param>
        /// <param name="node">SubTagGroup属性的Xml节点</param>
        /// <param name="eventTagRegister">西门子Tag注册委托</param>
        public SiemensSubTagGroup(
            CustomTagGroup parent,
            XmlNode node,
            TagRegisterHandler eventTagRegister) : base(parent, node)
        {
            _tagRegisterInParentHandler = eventTagRegister;
            _log  = Logger.Get <SiemensSubTagGroup>();
            _tags = new SiemensTagCollection(this, OnTagInGroupRegister);

            if (!(parent is SiemensTagGroup))
            {
                throw new Exception("parent对象必须是SiemensTagGroup对象");
            }

            _log.Trace($"创建[SubTagGroup={Prefix}]");

            XmlNode childNode = node.FirstChild;

            while (childNode != null)
            {
                SiemensTagCreator creator = new SiemensTagCreator();
                CustomTag         tag     = creator.CreateProduct(this, childNode);
                if (tag != null)
                {
                    _tags.Add(tag);
                }

                childNode = childNode.NextSibling;
            }
        }
 /// <summary>
 /// 构造方法
 /// </summary>
 /// <param name="parent">隶属的CustomTagGroup对象</param>
 public SiemensSubTagGroupCollection(CustomTagGroup parent) : base(parent)
 {
     if (!(parent is SiemensTagGroup))
     {
         throw new Exception("parent对象必须是SiemensTagGroup对象");
     }
 }
        /// <summary>
        /// 增加TagGroup对象
        /// </summary>
        /// <param name="group">TagGroup对象</param>
        public override void Add(CustomTagGroup group)
        {
            if (!(group is SiemensTagGroup))
            {
                throw new Exception("group对象必须是SiemensTagGroup对象");
            }

            SiemensTagGroup sGroup = group as SiemensTagGroup;

            if (sGroup.Parent != _parent)
            {
                throw new Exception("group对象隶属的设备和当前TagGroup集合不是同一个设备");
            }

            if (_groups.Keys.Contains(sGroup.Name))
            {
                throw new Exception($"当前TagGroup集合中已经存在[{sGroup.Name}]!");
            }

            _groups.Add(sGroup.Name, group);
        }
        /// <summary>
        /// 构造方法
        /// </summary>
        /// <param name="parent">TagGroup对象</param>
        /// <param name="node">SubTagGroup属性的Xml节点</param>
        public CustomSubTagGroup(CustomTagGroup parent, XmlNode node)
        {
            _parent =
                parent ??
                throw new Exception(
                          "传入的parent对象是null,SubTagGroup必须依赖于TagGroup对象");

            if (node == null)
            {
                throw new Exception("node对象不能是空值");
            }
            if (node.Name.ToUpper() != "SUBTAGGROUP")
            {
                throw new Exception(
                          $"传入的Xml节点不是[SubTagGroup],当前收到的Xml节点是:[{node.Name}]");
            }
            if (node.Attributes["Prefix"] == null)
            {
                throw new Exception("传入的Xml节点中没有[Prefix]属性定义,请注意大小写");
            }
            Prefix = node.Attributes["Prefix"].Value;
        }
        /// <summary>
        /// 查找指定的Tag
        /// </summary>
        /// <param name="name">标记组名称</param>
        /// <param name="tagName">标记名称</param>
        /// <returns>查找到的CustomTag对象,若没有找到则返回null</returns>
        public override CustomTag FindTag(string name, string tagName)
        {
            if (name == "" || tagName == "")
            {
                return(null);
            }

            string[] names        = name.Split('.');
            string   groupName    = names[0];
            string   subGroupName = names.Length >= 2 ? names[1] : "";

            CustomTagGroup group = _groups[groupName];

            if (group == null)
            {
                return(null);
            }
            else
            {
                if (subGroupName == "")
                {
                    return(((SiemensTagGroup)group).Tags[tagName]);
                }
                else
                {
                    CustomSubTagGroup subGroup = ((SiemensTagGroup)group).SubGroups[subGroupName];
                    if (subGroup == null)
                    {
                        return(null);
                    }
                    else
                    {
                        return(((SiemensSubTagGroup)subGroup).Tags[tagName]);
                    }
                }
            }
        }
        /// <summary>
        /// 构造方法
        /// </summary>
        public SiemensDevice(CustomPLC parent, XmlNode node) : base(parent, node)
        {
            _log = Logger.Get <SiemensDevice>();

            if (!(parent is SiemensPLC))
            {
                throw new Exception($"传入的PLC对象不是[SiemensPLC]对象");
            }
            else
            {
                Parent = parent;
            }

            #region 创建 Device
            if (node.Name.ToUpper() != "DEVICE")
            {
                throw new Exception($"Xml节点[{node.Name}]不是\"Device\"");
            }

            if (node.Attributes["DBType"] != null)
            {
                try
                {
                    DBType =
                        (SiemensRegisterType)Enum.Parse(
                            typeof(SiemensRegisterType),
                            node.Attributes["DBType"].Value);
                }
                catch
                {
                    string enumValues = "";
                    foreach (var value in Enum.GetValues(typeof(SiemensRegisterType)))
                    {
                        enumValues += $"[{value}]";
                    }
                    throw new Exception(
                              $"{node.Name}.{Name}节点中[DBType]属性值错误,只支持[{enumValues}]");
                }
            }
            else
            {
                throw new Exception(
                          $"{node.Name}.{Name}节点中未找到[DBType]属性,请注意属性名的大小写");
            }

            if (node.Attributes["DBNumber"] != null)
            {
                try
                {
                    DBNumber = int.Parse(node.Attributes["DBNumber"].Value);
                }
                catch
                {
                    throw new Exception(
                              $"{node.Name}.{Name}节点中[DBNumber]属性值错误,必须是整型值");
                }
            }
            else
            {
                throw new Exception(
                          $"{node.Name}.{Name}节点中未找到[DBNumber]属性,请注意属性名的大小写");
            }

            if (node.Attributes["CycleReadMode"] != null)
            {
                try
                {
                    CycleReadMode =
                        (SiemensCycleReadMode)Enum.Parse(
                            typeof(SiemensCycleReadMode),
                            node.Attributes["CycleReadMode"].Value);
                }
                catch
                {
                    string enumValues = "";
                    foreach (var value in Enum.GetValues(typeof(SiemensCycleReadMode)))
                    {
                        enumValues += $"[{value}]";
                    }
                    throw new Exception(
                              $"{node.Name}.{Name}节点中[CycleReadMode]属性值错误,只支持[{enumValues}]");
                }
            }

            if (node.Attributes["SplitterTime"] != null)
            {
                try
                {
                    SplitterTime = short.Parse(node.Attributes["SplitterTime"].Value);
                }
                catch (Exception error)
                {
                    _log.Error(
                        $"{node.Name}.{Name}节点中[SplitterTime]属性值错误,使用缺省10毫秒",
                        error);
                }
            }
            #endregion

            _log.Trace(
                $"创建设备[{Name}][DBType={DBType}|DBNumber={DBNumber}|" +
                $"CycleReadMode={CycleReadMode}]");

            #region 创建 Tag 组
            if (node.HasChildNodes)
            {
                CustomTagGroupCreator creator = new SiemensTagGroupCreator();
                XmlNode tagGroupNode          = node.FirstChild;
                while (tagGroupNode != null)
                {
                    if (tagGroupNode.Name.ToUpper() == "TAGGROUP")
                    {
                        try
                        {
                            CustomTagGroup group =
                                creator.CreateProuct(
                                    this,
                                    tagGroupNode,
                                    OnTagRegister);
                            _groups.Add(group);
                        }
                        catch (Exception error)
                        {
                            _log.Error(error.Message, error);
                        }
                    }

                    tagGroupNode = tagGroupNode.NextSibling;
                }
            }
            #endregion
        }
 /// <summary>
 /// 构造方法
 /// </summary>
 /// <param name="parent">所属的TagGroup对象,不允许空值</param>
 public CustomSubTagGroupCollection(CustomTagGroup parent)
 {
     _parent = parent ?? throw new Exception("parent参数不允许空值!");
     _groups = new Dictionary <string, CustomSubTagGroup>();
 }
 /// <summary>
 /// 增加TagGroup对象
 /// </summary>
 /// <param name="group">TagGroup对象</param>
 public abstract void Add(CustomTagGroup group);