Professional OPC
Development Tools

logos

Online Forums

Technical support is provided through Support Forums below. Anybody can view them; you need to Register/Login to our site (see links in upper right corner) in order to Post questions. You do not have to be a licensed user of our product.

Please read Rules for forum posts before reporting your issue or asking a question. OPC Labs team is actively monitoring the forums, and replies as soon as possible. Various technical information can also be found in our Knowledge Base. For your convenience, we have also assembled a Frequently Asked Questions page.

Do not use the Contact page for technical issues.

Subscribed tag failed to Trigger

More
18 Mar 2016 12:18 #3939 by support
Thanks for letting me know. I do not know Wonderware Intouch that much. My understanding is the conclusion of this case is that it had been a server-side issue, which can be either resolved or worked-around by modifying the configuration on the server side.

Best regards

Please Log in or Create an account to join the conversation.

More
18 Mar 2016 12:01 #3938 by Damian999
Thanks for your help.

We've found the problem.

We're using Wonderware Intouch to change the tags on a Timer using an "On True" condition. Apparently there is a know issue you with the "On True" condition. We've switch to using "While True" and this has solved the problem.

Again Thanks for your help.

Damian

Please Log in or Create an account to join the conversation.

More
16 Mar 2016 08:57 #3931 by support
Hello,
thanks for the code.

I do not see any real problem with it. The handler logic should ideally be somewhat different, but that's not serious. Normally you would test for the .Exception first: If that is non-null, then Vtq *is* null, and the .Exception (and other properties) gives more info about the problem. If .Exception is null, then Vtq is always non-null, and contains what the server has sent. More details: E.g. the Concepts document, section Best Practices ("Always test the Exception property before accessing the actual result (Value, Vtq, or AttributeData property)".

I assume you do not see any errors (in the .Exception; or, in your logic, null-Vtq-s or bad Qualities) during those 72 hours? If so, we should start looking into the details of these errors first.

If there are no errors, and you still think you are missing some updates, what is the evidence for that claim? Do you have some server log, or info from other OPC client?

If everything else fails, a special tool (OPC Analyzer) can be used to log the traffic between the client and the server.

--
And (hopefully unrelated to the problem you reported): Please do *not* use the Handle to identify the subscribed item in the callback handler. For explanation, see the Concepts document, section Best Practices: "Use the state instead of handles to identify subscribed entities".

Best regards

Please Log in or Create an account to join the conversation.

More
16 Mar 2016 07:55 #3930 by support
I apologize for delay; the site was down yesterday. I plan to reply during today.

Please Log in or Create an account to join the conversation.

More
14 Mar 2016 16:57 - 14 Mar 2016 17:29 #3929 by Damian999
Thanks for the quick reply.

>Do you also access the subscribed tag in some other way? E.g. by reading it from time, either using QuickOPC, or some other OPC client?

No this is the only method we are accessing the tag.


The code is divided in 2 layers...

OpcClient Layer
public int SubscribeItem(ITag tag, Action<ITag, TagValueChangedEventArgs> onChangeAction)
        {
            int requestedUpdateRate = 1000;
 
            //The method returns an integer handle that uniquely identifies the item subscription.
            var result = _easyDaClient.SubscribeItem(
                _plcParamereters.MachineName,
                _plcParamereters.ServerClass,
                tag.Name,
                requestedUpdateRate,
                TagValueChangedCallback
                );
 
            _callbacks.Add(result, new TagValueChangedCallback { Tag = tag, TagValueChangedAction = onChangeAction });
 
            return result;
        }
 
        private void TagValueChangedCallback(object sender, EasyDAItemChangedEventArgs e)
        {
            Debug.WriteLine(e.ToString());
 
            TagValueChangedCallback tagValueChangedCallback = null;
 
            try
            {
                var subscribedItem = e.Handle;
 
                tagValueChangedCallback = _callbacks[subscribedItem];
            }
            catch (KeyNotFoundException)
            {
            }
 
            if (tagValueChangedCallback == null)
                throw new Exception("OpcClientCallback not defined");
 
            if (e.Vtq == null || e.Vtq.Value == null)
            {
                var message = string.Format("Tag value invalid: tag:{0};", tagValueChangedCallback.Tag.Name);
                Debug.WriteLine(message);
            }
 
            var tagValueChangedEventArgs = new TagValueChangedEventArgs
            {
                Value = e.Vtq == null ? null : e.Vtq.Value,
                Quality = e.Vtq == null ? string.Empty : e.Vtq.Quality.ToString(),
                QualityIsGood = e.Vtq != null && e.Vtq.Quality.IsGood(),
                Timestamp = e.Vtq == null ? DateTime.MinValue : e.Vtq.Timestamp,
                ErrorCode = e.ErrorCode,
                ErrorMessage = e.ErrorMessage,
                Exception = e.Exception
            };
 
            // update the tag value
            if (e.Vtq != null && e.Vtq.Value != null)
                tagValueChangedCallback.Tag.Value = e.Vtq.Value;
 
            // invoke the callback delegate
            tagValueChangedCallback.TagValueChangedAction(tagValueChangedCallback.Tag, tagValueChangedEventArgs);
        }
 

Application Layer
//Master Start Constructor
 
        public MasterStart(
            ILogWriter logWriter,
            IEdhrQueryResultHandler edhrQueryResultHandler,
            IPlcClient plcClient,
            ITagNameGenerator tagNameGenerator
            )
            : base(
                logWriter,
                edhrQueryResultHandler,
                plcClient,
                tagNameGenerator
                )
        {
 
 
 
            _tagEventTriggerFlag = new Tag<bool>(TagNameGenerator.Generate("lsNextLotCheck"));
 
            _tagErrorNum = new Tag<int>(TagNameGenerator.Generate("lsErrorNum"));
            _tagErrorDescription = new Tag<string>(TagNameGenerator.Generate("lsErrorDescription"));
 
            _tagMasterNo = new Tag<string>(TagNameGenerator.Generate("lsLotNoNext"));
 
 
 
 
            _masterStartTags = new List<ITag>
            {
 
                _tagMasterNo,
 
            };
 
 
 
            // subscribe for tag change events
            PlcClient.SubscribeItem(_tagEventTriggerFlag, MasterStartFlag_OnChange);
        }
 
 
 
//Master Start on Change
        private void MasterStartFlag_OnChange(ITag tag, TagValueChangedEventArgs args)
        {
 
 
            const string eventName = "LotStart";
 
            try
            {
 
                // read PLC tags
                PlcClient.ReadMultipleItemValues(_masterStartTags);
 
 
                if (!_tagEventTriggerFlag.Value)
                {
                    return;
                }
 
 
 
                WriteTolog("Starting Event with Value " + _tagMasterNo.Value + " - " + _tagEventTriggerFlag.Value, eventName, true);
 
		// Do database work....
 
 
            }
            catch (Exception ex)
            {
                WriteTolog(ex, eventName);
                _tagEventTriggerFlag.Value = false;
                _tagErrorDescription.Value = ex.Message;
                _tagErrorNum.Value = ProductionEventConstants.EDHR_ERROR; //Set to 2 to flag 
 
                try
                {
                    // Write tags to PLC
                    PlcClient.WriteMultipleItemValues(new List<ITag> { _tagEventTriggerFlag, _tagErrorDescription, _tagErrorNum });
                }
                catch (Exception)
                {
                    // ignored
                }
            }
        }
Last edit: 14 Mar 2016 17:29 by support. Reason: code formatting

Please Log in or Create an account to join the conversation.

More
14 Mar 2016 16:16 #3928 by support
Hello.

Do you also access the subscribed tag in some other way? E.g. by reading it from time, either using QuickOPC, or some other OPC client?

The reason I am asking is because we have seen servers "confusing" the different accesses (that should be independent), and then forgetting to send the right update.

Also, can you please post the piece of code (or basic structure of it) that handles the data change notification? Reason: I want to check whether the various situations that can emerge (esp. the error checking) are done right.

Thank you

Please Log in or Create an account to join the conversation.

More
14 Mar 2016 15:34 #3927 by Damian999
Hi, it appears on that on occasion that our application "misses" a tag change from a subscribed tag.

We are using QuickOPC v5.23 with Wonderware FS Gateway 2.0.1 and Wonderware InTouch 10.5.001.

Our application is subscribed to 1 tag.
Intouch changes this tag every minute.
Over the course of 72 hours in testing it appears from our logs that our application missed the tag change on 79 occasions.

What is the best way to attempt to diagnose the problem?


Damian

Please Log in or Create an account to join the conversation.

Moderators: support
Time to create page: 0.058 seconds