示例#1
0
 internal void RaiseTagQualityChanged(LogixTag sender)
 {
     if (TagQualityChanged != null)
     {
         TagQualityChanged(sender, new TagQualityChangedEventArgs(sender));
     }
 }
示例#2
0
        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);
            }
        }
        /// <summary>
        /// Writes a single tag
        /// </summary>
        /// <param name="tag">Tag to write</param>
        /// <returns>True if the write was successful</returns>
        /// <remarks>This is not the preferred method of updating tag information. If you have
        /// multiple tags that you want to update, use the <see cref="UpdateGroups"/> method.</remarks>
        public bool WriteTag(ITag tag)
        {
            lock (_lockObject)
            {
                LogixTag lgxTag = tag as LogixTag;

                if (lgxTag == null)
                {
                    throw new ArgumentException(Resources.ErrorStrings.IncorrectArgTagType, "tag");
                }

                WriteDataServiceReply lgxWrite = LogixServices.WriteLogixData(_session, lgxTag.Address, lgxTag.DataType, (ushort)lgxTag.Elements, lgxTag.GetWriteData(), lgxTag.StructHandle);

                if (lgxWrite == null)
                {
                    return(false);
                }

                if (lgxWrite.Status == 0x00)
                {
                    lgxTag.ClearPendingWrite();
                    return(true);
                }
            }

            return(false);
        }
示例#4
0
 internal void RaiseTagDataChanged(LogixTag sender)
 {
     if (TagValueUpdated != null)
     {
         TagValueUpdated(sender, new TagValueUpdateEventArgs(sender));
     }
 }
示例#5
0
 /// <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>
        /// Reads a single tag
        /// </summary>
        /// <param name="tag">Tag to read</param>
        /// <returns>True if the read was successful</returns>
        /// <remarks>This is not the preferred method of updating tag information. If you have
        /// multiple tags that you want to update, use the <see cref="UpdateGroup"/> method.</remarks>
        public bool ReadTag(ITag tag)
        {
            lock (_lockObject)
            {
                LogixTag lgxTag = tag as LogixTag;

                if (lgxTag == null)
                {
                    throw new ArgumentException(Resources.ErrorStrings.IncorrectArgTagType, "tag");
                }

                ReadDataServiceReply lgxRead = LogixServices.ReadLogixData(_session, lgxTag.Address, (ushort)lgxTag.Elements);

                if (lgxRead == null || lgxRead.Data == null)
                {
                    if (lgxRead != null)
                    {
                        lgxTag.SetTagError(lgxRead.ByteStatus);
                    }

                    lgxTag.LastError       = Resources.ErrorStrings.TagNotFound + _ipAddress;
                    lgxTag.LastErrorNumber = (int)LogixErrors.TagNotFound;
                    return(false);
                }

                lgxTag.SetTagError(lgxRead.ByteStatus);
                CIPType tagType = (CIPType)lgxRead.DataType;
                byte[]  temp    = new byte[lgxRead.Data.Length + 2];
                Buffer.BlockCopy(BitConverter.GetBytes(lgxRead.DataType), 0, temp, 0, 2);
                Buffer.BlockCopy(lgxRead.Data, 0, temp, 2, lgxRead.Data.Length);

                lgxTag.UpdateValue(temp);

                uint offset = (uint)lgxRead.Data.Length;

                if (lgxRead.Status == 0x06)
                {
                    //We are going to have to request more data...
                    while (lgxRead.Status == 0x06)
                    {
                        lgxRead = LogixServices.ReadLogixDataFragmented(_session, lgxTag.Address, (ushort)lgxTag.Elements, offset);
                        lgxTag.SetTagError(lgxRead.ByteStatus);

                        tagType = (CIPType)lgxRead.DataType;
                        temp    = new byte[lgxRead.Data.Length + 2];
                        Buffer.BlockCopy(BitConverter.GetBytes(lgxRead.DataType), 0, temp, 0, 2);
                        Buffer.BlockCopy(lgxRead.Data, 0, temp, 2, lgxRead.Data.Length);

                        lgxTag.UpdateValue(temp, offset);

                        offset += (uint)lgxRead.Data.Length;
                    }
                }
            }       //End Lock

            return(true);
        }
示例#7
0
 /// <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);
     }
 }
        /// <summary>
        /// Adds a tag to the processor
        /// </summary>
        /// <param name="tag">Tag to add (must be a LogixTag)</param>
        /// <returns>True if the tag was successfully added</returns>
        /// <remarks>This is used by the tag service to verify the
        /// tag actually exists.</remarks>
        internal bool AddTag(LogixTag tag)
        {
            //Here is the procedure for adding a tag:
            //1. Run some verification tests on the tag first
            //2. First create a read request for a single tag
            //3. Send the request to the PLC
            //4. Verify the response and data type
            //5. Store it in the tag

            LogixTag lgxTag = tag as LogixTag;

            if (lgxTag == null)
            {
                throw new ArgumentException(Resources.ErrorStrings.IncorrectArgTagType, "tag");
            }

            if (!ReadTag(lgxTag))
            {
                return(false);
            }

            return(true);
        }
示例#9
0
        static void WriteStructure(LogixTag tag, LogixProcessor processor)
        {
            Console.Write("The tag is a structure called " + ((LogixUDT)tag).TypeName + ", please enter a member name: ");
            string memberName = Console.ReadLine();

            //First we have to find out if the member exists, if it doesn't we can't write to it...
            List<string> memberNames = ((LogixUDT)tag).MemberNames;

            bool hasMember = false;
            for (int i = 0; i < memberNames.Count; i++)
            {
                if (string.Compare(memberNames[i], memberName) == 0)
                {
                    hasMember = true;
                    break;
                }
            }

            if (!hasMember)
            {
                Console.WriteLine("The specified member could not be found in the structure");
                return;
            }

            Console.Write("Enter a value: ");
            string sValue = Console.ReadLine();

            //Now we have to convert it to the right type...
            try
            {
                switch (tag.LogixType)
                {
                    case LogixTypes.Bool:
                        if (sValue == "1")
                            ((LogixUDT)tag)[memberName] = true;
                        else
                            ((LogixUDT)tag)[memberName] = false;
                        break;
                    case LogixTypes.DInt:
                        ((LogixUDT)tag)[memberName] = Convert.ToInt32(sValue);
                        break;
                    case LogixTypes.Int:
                        ((LogixUDT)tag)[memberName] = Convert.ToInt16(sValue);
                        break;
                    case LogixTypes.LInt:
                        ((LogixUDT)tag)[memberName] = Convert.ToInt64(sValue);
                        break;
                    case LogixTypes.Real:
                        ((LogixUDT)tag)[memberName] = Convert.ToSingle(sValue);
                        break;
                    case LogixTypes.SInt:
                        ((LogixUDT)tag)[memberName] = Convert.ToSByte(sValue);
                        break;
                    case LogixTypes.User_Defined:
                    default:
                        Console.WriteLine("This demo does not support writing to nested structure tags");
                        return;
                }

                //At this point the tag has not been committed to the processor. The
                //tag must be written, then read back for the value to change. The
                //easiest way to do this with a single tag is to use the processor
                //LogixProcessor.WriteRead() which performs the write, then the
                //subsequent read on the tag.
                processor.WriteRead(tag);
            }
            catch (Exception e)
            {
                Console.WriteLine("Could not convert " + sValue + " to the correct type for " + tag.Address);
            }
        }
示例#10
0
        static void WriteOther(LogixTag tag, LogixProcessor processor)
        {
            Console.Write("Enter a value: ");
            string sValue = Console.ReadLine();

            //Now we have to convert it to the right type...
            try
            {
                switch (tag.LogixType)
                {
                    case LogixTypes.DInt:
                        ((LogixDINT)tag).Value = Convert.ToInt32(sValue);
                        break;
                    case LogixTypes.Int:
                        ((LogixINT)tag).Value = Convert.ToInt16(sValue);
                        break;
                    case LogixTypes.LInt:
                        ((LogixLINT)tag).Value = Convert.ToInt64(sValue);
                        break;
                    case LogixTypes.Real:
                        ((LogixREAL)tag).Value = Convert.ToSingle(sValue);
                        break;
                    case LogixTypes.SInt:
                        ((LogixSINT)tag).Value = Convert.ToSByte(sValue);
                        break;
                    default:
                        return;
                }

                //At this point the tag has not been committed to the processor. The
                //tag must be written, then read back for the value to change. The
                //easiest way to do this with a single tag is to use the processor
                //LogixProcessor.WriteRead() which performs the write, then the
                //subsequent read on the tag.
                processor.WriteRead(tag);
            }
            catch (Exception e)
            {
                Console.WriteLine("Could not convert " + sValue + " to the correct type for " + tag.Address);
            }
        }
示例#11
0
        static void WriteBool(LogixTag tag, LogixProcessor processor)
        {
            Console.WriteLine("Enter 1 for True, 0 for False: ");
            char key = Console.ReadKey().KeyChar;

            if (key == '1')
                ((LogixBOOL)tag).Value = true;
            else
                ((LogixBOOL)tag).Value = false;

            //At this point the tag has not been committed to the processor. The
            //tag must be written, then read back for the value to change. The
            //easiest way to do this with a single tag is to use the processor
            //LogixProcessor.WriteRead() which performs the write, then the
            //subsequent read on the tag.
            processor.WriteRead(tag);
        }
示例#12
0
 static void PrintTagValue(LogixTag tag)
 {
     //Now we'll determine the value of the tag...
     switch (tag.LogixType)
     {
         case LogixTypes.Bool:
             Console.WriteLine("BOOL value is: " + ((LogixBOOL)tag).Value.ToString());
             break;
         case LogixTypes.Control:
             //The control tag is a lot more complicated, there is no way currently to know
             //which member was updated, so all you can do is say it was updated, we'll print
             //out one of the members though.
             Console.WriteLine("Control.POS is: " + ((LogixCONTROL)tag).POS.ToString());
             break;
         case LogixTypes.Counter:
             //Same as the counter above, we'll just print out the ACC value
             Console.WriteLine("Counter.ACC value is: " + ((LogixCOUNTER)tag).ACC.ToString());
             break;
         case LogixTypes.DInt:
             //Print out the value. DINT's are equivalent to int in .NET
             Console.WriteLine("DINT value is: " + ((LogixDINT)tag).Value.ToString());
             break;
         case LogixTypes.Int:
             //An INT in a logix processor is more like a short in .NET
             Console.WriteLine("INT value is: " + ((LogixINT)tag).Value.ToString());
             break;
         case LogixTypes.LInt:
             //LINT's are equivalent to long in .NET
             Console.WriteLine("LINT value is: " + ((LogixLINT)tag).Value.ToString());
             break;
         case LogixTypes.Real:
             //REALs are single precision floats
             Console.WriteLine("REAL value is: " + ((LogixREAL)tag).Value.ToString());
             break;
         case LogixTypes.SInt:
             //SINTs are signed bytes
             Console.WriteLine("SINT value is: " + ((LogixSINT)tag).Value.ToString());
             break;
         case LogixTypes.String:
             //Strings are just like .NET strings, so notice how we can skip the .StringValue
             //member, since the .ToString() will automatically be called, which returns the
             //same value as .StringValue
             Console.WriteLine("STRING value is: " + ((LogixSTRING)tag));
             break;
         case LogixTypes.Timer:
             //Timers again are like the CONTROL and COUNTER types
             Console.WriteLine("Timer.ACC value is: " + ((LogixTIMER)tag).ACC.ToString());
             break;
         case LogixTypes.User_Defined:
             //The only way to get the value out of a UDT, PDT, or MDT is to define the
             //structure or know the member name you wish to read. We'll just print that
             //we know its a UDT, MDT, or PDT that changed.
             Console.WriteLine("User defined type");
             break;
         default:
             break;
     }
 }
示例#13
0
        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);

            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);
                        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);
            }
        }
示例#14
0
 internal void RaiseTagQualityChanged(LogixTag sender)
 {
     if (TagQualityChanged != null)
         TagQualityChanged(sender, new TagQualityChangedEventArgs(sender));
 }
示例#15
0
 internal void RaiseTagDataChanged(LogixTag sender)
 {
     if (TagValueUpdated != null)
         TagValueUpdated(sender, new TagValueUpdateEventArgs(sender));
 }