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.

Update server after property changed

More
20 May 2019 07:20 #7399 by support
There really isn't any reliable way to determine what the cause of the incoming change - whether it was your Write, or something else. There are issues with other suggested approaches as well, because due to timing/delays, whenever you have two actors (your code, and something in the server) changing the same item, and making decisions based on its value, one actor may overwrite the correct value by an incorrect one.

I have seen customers struggling with similar issues in the past. I think the solution is to redesign the logic system to something that does not suffer from the timing/overwrite issue - that usually involves using at least two items, and a kind of "handshaking" algorithm where receival of every transition made by one party gets acknowledged by the receiving party. But in some cases, there may be other solutions and tricks - that really depends on the particular task at hand.

The OPC here serves as a "transport mechanism" only. It functions quite logically, if you think about. One needs, however, to think through all the consequences.

Regards

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

More
20 May 2019 05:15 #7398 by RND
Thank you, I think I understand and apologize for not being clear. I was imagining a super simple setter like:
private bool _motorDisabled;
public bool MotorDisabled
{
     get => _motorDisabled;
     set
     {
          _motorDisabled = value;   // or SetProperty(ref _motorDisabled, value);
          WriteThisValueToTheOPCServer();
     }
}

A better way for me to ask the question would have been: Is there a way for the code in the setter to know that the value was just changed by the QuickOPC mapper as a result of a change in the subscribed value, OR was it set from within the local application expecting it to also be written to the server. The write would be unnecessary if the change just came from the server, but would be necessary if the change came from the application and needed to be reflected in the server.

I think from your answer, you're saying that there wouldn't be a circular issue because if the mapper changed that value to true and the setter then inefficiently wrote it back to the server, nothing would happen because the QuickOPC/Server would note that an unchanged value was being written and it would be ignored. Hence, no circular condition.

I realize that the write could be conditional on whether the stored private value is different from the new value.
     set
     {
          if (value != _motorDisabled)
          {
               _motorDisabled = value;
               WriteThisValueToTheOPCServer();
          }
     }

A locally initiated change would make the write, but when the subscription change event comes back after a successful change in the server, the write would be prevented. But, if the change was initiated by the server, the setter would note the change and then make the unnecessary/inefficient write. The OPCServer would be ok with it because the node was already that value and not cause a new subscription change event. (I think)

I appreciate your quick response, unfortunately the notification went to my spam folder and I only just now found it, so sorry for my late acknowledgement.

Thanks,
Rick

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

More
03 May 2019 07:53 #7340 by support
Well, your question has two aspects I think, and I am not sure which one you are concerned about:

1. The "logical" aspect - WHAT actually happens. Well, if, for example, you have a read/write binary tag in the server, and you program your client so that whenever it gets a value of that tag, it negates it and writes it back to the server, you will create an oscillation. Its parameters (frequency etc.) will depend on timing of various parts involved in the process. The fact that this happens is totally independent on the programming model or library you are using - it is a matter of principle. It may be be undesirable ( a mistake), or , in fact, quite desirable : In a sense, each control loop is an example of such circularity, although more indirect and complex.

2. The "physical" aspect - HOW it works (and whether it is supported). There are some settings and techniques in QuickOPC which allows you to influence the behavior. But, to make the explanation, in the default state, you do not need to worry about some kind of infinite recursion. The updates from the server are queued and come on a separate thread, so when you do the "write", the corresponding update from the server will not come back to you on the same thread while still "inside" the Write.

Also, to this part of your post: "Doesn't the setter execute when the change comes from the OPC server" - that depends on how you annotate it. Only if it is made to receive subscription updates (or read results, and you are calling the Read), the answer is Yes.

Best regards
The following user(s) said Thank You: RND

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

More
03 May 2019 03:50 #7338 by RND
I can easily carry a reference to the mapper in my mapped object. But, I have a question about your suggestion. Doesn't the setter execute when the change comes from the OPC server? If so, and you want to put an explicit Mapper.WriteTarget in the same setter, how do you prevent this from being circular where the change coming in from the OPCServer immediately triggers a write back to the OPCServer? I am new to this library and my have misunderstood your suggestion.

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

More
25 Jan 2017 10:46 #4887 by support
Unfortunately we do not support that currently; it is not precisely "in line" with the design concept of Live Mapping. Here is some workaround:

1) Somehow make the reference to the mapper object (UAClientMapper) available to your mapped objects. This may be easy, or the hardest part, it depends on your application. Ideally you would put the mapper reference in each mapped object or have a function to retrieve it, but if you have just one mapper instance in the whole project, even "hacks" like using a static property on some class may be used.

2) Add following annotation to your Available property:
[MappingTag("Available")]
3) Inside the property setter, call (where Mapper comes from bullet 1 above):
Mapper.WriteTarget(this, "Available", /*recurse:*/false);
This should do it.

I have made a note and we will think about whether/how to make the Mapper easier accessible in future version, maybe as an additional meta-member.
The following user(s) said Thank You: Captain_Dash

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

More
24 Jan 2017 15:59 #4885 by Captain_Dash
precisely

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

More
24 Jan 2017 12:00 #4882 by support
So, you want the call to a setter of the Available property invoke an OPC Write of that value immediately, right?

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

More
24 Jan 2017 08:25 #4880 by Captain_Dash
Hello,

thanks for the fast reply. Just to clearify to you what i'm trying to achieve ist that i have a data class with its properties which i want to bind to the applications gui. To keep the data consistent between opc server and the application i would like to have a two way subscription which is getting the data changes from the server as well as sending the changes from the user to the server just without using a separat write command or inject the mapper class to data class itself.

For Example I only want to declare a property like this
        [UANode(BrowsePath = ".b_available"), 
        UAData(Operations = UADataMappingOperations.All, Kind = UADataMappingKind.Value),
        UAMonitoring(SamplingInterval = 20), UASubscription(PublishingInterval = 200)]
        public bool Available
        {
            get { return this.available; }
            set { this.SetProperty(ref this.available, value); }
        }
 
        private bool available;

and create the two way binding.

I saw a similiar example on a other client sdk and just want to know if opc labs is supporting such a feature, too.

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

More
23 Jan 2017 19:30 #4876 by support
Hello.

The way it as envisioned was with the Write operation on the mapper object (but I understand that for some reason you do not want that).

Alternatively, you can step away from Live Mapping for this purpose, use the EasyUAClient object and call Write/WriteValue on it. The meta-members may help you to obtain the identification information needed (opclabs.doc-that.com/files/onlinedocs/QuickOpc/Latest/User%2...ebframe.html#Meta-Members.html ).

But I am not completely sure whether I have understood what you expect. If you expected something else, please let me know and try to describe a bit more elaborately what you are trying to achieve.

Best regards

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

More
23 Jan 2017 17:15 #4875 by Captain_Dash
Hello,

First of all I am using VS 2015 and programming an wpf application via MVVM.
I subscribed a data class with its properties to a similiar structure on our opc server successfully with the attributes of your live mapping feature. I'm getting the updated values if the data on the server changes. But if I want to do it the other way around, which means the user changes data in the live mapped class through our application the data will not be transfered automatically to the server. Can you tell me what steps would be necessary to do it?
I figured out, if i'm calling the write method the changes will be transfered, but i do not want give the UAClientMapper instance to the data class where the live mapping is happening.

Thanks in advance
André

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

Moderators: support
Time to create page: 0.078 seconds