/// <summary> /// 构造方法 /// </summary> /// <param name="parent">TagGroup对象所依赖的Device对象</param> /// <param name="node">TagGroup对象属性的Xml节点</param> /// <param name="eventTagRegister">西门子Tag注册委托</param> public SiemensTagGroup( CustomDevice parent, XmlNode node, TagRegisterHandler eventTagRegister) : base(parent, node) { if (!(parent is SiemensDevice)) { throw new Exception("parent对象必须是SiemensDevice对象"); } if (node.Name.ToUpper() != "TAGGROUP") { throw new Exception($"Xml节点[{node.Name}]不是\"TagGroup\""); } _tagRegisterInParentHandler = eventTagRegister; _log = Logger.Get <SiemensTagGroup>(); _tags = new SiemensTagCollection(this, OnTagInGroupRegister); _groups = new SiemensSubTagGroupCollection(this); _log.Trace($"创建TagGroup[{Name}]"); #region 创建Tag if (node.HasChildNodes) { SiemensTagCreator creator = new SiemensTagCreator(); XmlNode childNode = node.FirstChild; while (childNode != null) { string nodeName = childNode.Name.ToUpper(); switch (nodeName) { case "TAG": CustomTag tag = creator.CreateProduct(this, childNode); if (tag != null) { _tags.Add(tag); } break; case "SUBTAGGROUP": SiemensSubTagGroup subTagGroup = new SiemensSubTagGroup( this, childNode, OnTagInGroupRegister); if (subTagGroup != null) { _groups.Add(subTagGroup); } break; } childNode = childNode.NextSibling; } } #endregion }
/// <summary> /// 根据关键字处理指定TagGroup所对应的数据块数据 /// </summary> private void DealPartBlockBuffer(string key, byte[] buffer) { PLCDBBlock block = ControlBlock[key]; if (block != null && key != "COMM") { _log.Debug( $"[{key}.Offset={block.Start_Offset}, " + $"{key}.Length={block.BufferLength}]"); _log.Debug($"[{key}]|[Data:{Tools.BytesToBCD(buffer)}]"); } // 根据key解析出TagGroup和SubTagGroup string[] keys = key.Split('.'); string keyTagGroup = keys[0]; string keySubTagGroup = ""; if (keys.Length >= 2) { keySubTagGroup = keys[1]; } SiemensTagGroup group = _groups[keyTagGroup] as SiemensTagGroup; if (group == null) { _log.Error($"设备[{Name}]未找到[{keyTagGroup}]Tag组"); return; } if (keySubTagGroup == "") { SetControlTagValueInGroup(group, buffer, block.Start_Offset); } else { SiemensSubTagGroup subGroup = group.SubGroups[keySubTagGroup] as SiemensSubTagGroup; if (subGroup == null) { _log.Error($"设备[{Name}]未找到[{keyTagGroup}.{keySubTagGroup}]Tag组"); return; } else { SetControlTagValueInGroup(subGroup, buffer, block.Start_Offset); } } }
/// <summary> /// 设置控制Tag值 /// </summary> /// <param name="group">SubTagGroup对象</param> /// <param name="buffer">数据块内容</param> /// <param name="offset">当前数据块内容在整个数据块的起始偏移量</param> private void SetControlTagValueInGroup( SiemensSubTagGroup group, byte[] buffer, int offset) { foreach (CustomTag tag in group.Tags) { if (tag.Type == TagType.C) { if (SetTagValue(buffer, tag, offset)) { ControlTagValueChanged(tag); } } } }
/// <summary> /// Tag对象注册事件 /// </summary> /// <param name="group">TagGroup对象</param> /// <param name="tag">Tag对象</param> private void OnTagRegister(CustomGroup group, CustomTag tag) { _log.Trace($"Device[{Name}]:Tag[{tag.Name}],Offset[{tag.DB_Offset}]"); if (!(tag is SiemensTag)) { throw new Exception($"tag对象:{tag.Name}不是SiemensTag对象"); } SiemensTag siemensTag = tag as SiemensTag; switch (CycleReadMode) { case SiemensCycleReadMode.FullBlock: FullBlock.Add(siemensTag.DB_Offset, siemensTag.Length); break; case SiemensCycleReadMode.ControlBlock: if (siemensTag.Type == TagType.C) { string key = ""; if (group is SiemensTagGroup) { key = (group as SiemensTagGroup).Name; } else if (group is SiemensSubTagGroup) { SiemensSubTagGroup subGroup = group as SiemensSubTagGroup; key = $"{subGroup.Parent.Name}.{subGroup.Prefix}"; } PLCDBBlock block = ControlBlock[key]; if (block == null) { block = new PLCDBBlock(); ControlBlock.Add(key, block); } block.Add(siemensTag.DB_Offset, siemensTag.Length); } break; } }
/// <summary> /// 增加SubTagGroup对象 /// </summary> /// <param name="group">SubTagGroup对象</param> public override void Add(CustomSubTagGroup group) { if (!(group is SiemensSubTagGroup)) { throw new Exception("group对象必须是SiemensSubTagGroup对象"); } SiemensSubTagGroup sGroup = group as SiemensSubTagGroup; if (sGroup.Parent != _parent) { throw new Exception("group对象隶属的TagGroup和当前SubTagGroup集合不是同一个TagGroup"); } if (_groups.Keys.Contains(sGroup.Prefix)) { throw new Exception($"当前SubTagGroup集合中已经存在前缀[{sGroup.Prefix}]的SubTagGroup!"); } _groups.Add(sGroup.Prefix, group); }