/// <summary> /// Removes a tag from this tag group /// </summary> /// <param name="tag">Tag to be removed</param> /// <remarks> /// <para>Removing a tag triggers the tag group to re-optimize all /// of the tag read requests. This can be a long process for groups /// with large numbers of tags or tags that require a lot of data to /// be transferred.</para> /// <para>It is recommended that if you only need to remove a couple /// tags from a group that you disable them instead. Disabled tags /// will no longer update the value or send out update events.</para> /// </remarks> public void RemoveTag(LogixTag tag) { //lock (_lockObject) { _tags.Remove(tag); RebuildReadRequests(); } }
/// <summary> /// Adds a tag to this tag group /// </summary> /// <param name="tag">Tag to be added</param> /// <remarks> /// <para>It is recommended that you create your groups once, then /// enable or disable them as you need them. Don't <see cref="RemoveTag"/> /// frequently, as this may degrade the performance of your application.</para> /// </remarks> public void AddTag(LogixTag tag) { //lock (_lockObject) { int idx = _tags.Count; _tags.Add(tag); AddOrCreateReadPacket(_tags[idx], idx); } }
public static ReadDataServiceRequest BuildLogixReadDataRequest(LogixTag tag, ushort number, out int requestSize) { if (tag.TagInfo != null && tag.TagInfo.IsStructure == false && tag.TagInfo.Dimensions == 0) { //Short version ushort size = 0; switch ((CipType)tag.TagInfo.DataType) { case CipType.BITS: case CipType.BOOL: size = 1; break; case CipType.DINT: size = 4; break; case CipType.INT: size = 2; break; case CipType.LINT: size = 8; break; case CipType.REAL: size = 4; break; case CipType.SINT: size = 1; break; default: return(BuildLogixReadDataRequest(tag.Address, number, out requestSize)); } return(BuildShortReadDataRequest(tag.TagInfo.MemoryAddress, number, size, out requestSize)); } else { //Long version return(BuildLogixReadDataRequest(tag.Address, number, out requestSize)); } }
private void AddOrCreateReadPacket(LogixTag tag, int idx) { //First we create the request... int temp = 0; ReadDataServiceRequest request = LogixServices.BuildLogixReadDataRequest( tag.Address, tag.Elements, out temp); //Now we read it from the PLC to find out if it's fragmented... CommonPacketItem addressItem = CommonPacketItem.GetConnectedAddressItem(_parent.SessionInfo.ConnectionParameters.O2T_CID); CommonPacketItem dataItem = CommonPacketItem.GetConnectedDataItem(request.Pack(), SequenceNumberGenerator.SequenceNumber(_parent.SyncRoot)); //ToDo _parent.SyncRoot EncapsReply reply = _parent.SessionInfo.SendUnitData(addressItem, dataItem); if (reply != null) { //It's a good tag, let's figure out if it's fragmented... ReadDataServiceReply rdReply = new ReadDataServiceReply(reply); PacketMap pm = new PacketMap() { TagIndex = idx }; pm.PacketIndex = new List <int>(); pm.ServiceIndex = new List <int>(); pm.Offsets = new List <uint>(); pm.NumReplies = 1; if (rdReply.Status == 0x06) { //Partial read... We'll have to request more data, but first let's make this packet request = LogixServices.BuildFragmentedReadDataRequest(tag.Address, tag.Elements, 0, out temp); int[] status = FindPacketOrCreate(request.Pack(), (ushort)(rdReply.Data.Length + 2)); uint offset = (uint)rdReply.Data.Length; pm.PacketIndex.Add(status[0]); pm.ServiceIndex.Add(status[1]); pm.Offsets.Add(0); while (rdReply.Status == 0x06) { rdReply = LogixServices.ReadLogixDataFragmented(_parent.SessionInfo, tag.Address, tag.Elements, offset, _parent.SyncRoot); //ToDo _parent.SyncRoot request = LogixServices.BuildFragmentedReadDataRequest(tag.Address, tag.Elements, offset, out temp); status = FindPacketOrCreate(request.Pack(), (ushort)(rdReply.Data.Length + 2)); pm.PacketIndex.Add(status[0]); pm.ServiceIndex.Add(status[1]); offset += (uint)rdReply.Data.Length; pm.Offsets.Add(offset); pm.NumReplies++; } } else if (rdReply.Status == 0x00 && rdReply.Data != null) { //Full read, create the packet... int[] status = FindPacketOrCreate(request.Pack(), (ushort)(rdReply.Data.Length + 2)); pm.PacketIndex.Add(status[0]); pm.ServiceIndex.Add(status[1]); pm.Offsets.Add(0); } _readPackets.Add(pm); } }
internal void RaiseTagQualityChanged(LogixTag sender) { TagQualityChanged?.Invoke(sender, new TagQualityChangedEventArgs(sender)); }
internal void RaiseTagDataChanged(LogixTag sender) { TagValueUpdated?.Invoke(sender, new TagValueUpdateEventArgs(sender)); }