简体   繁体   English

UTGARD opc客户端:重复读取多个项目

[英]UTGARD opc client: Read multiple items repeatedly

I have written the following code using the Utgard OPC library. 我已经使用Utgard OPC库编写了以下代码。

I need to read data from an OPC server once every 15 seconds. 我需要每15秒从OPC服务器读取一次数据。 However, I'm not sure if this is the most optimal way to implement it. 但是,我不确定这是否是实现它的最佳方法。 In my scenario I require to read upward of 300 tags from the server. 在我的场景中,我需要从服务器上读取300个以上的标签。

Any suggestions? 有什么建议么?

package opcClientSalem;
import java.util.concurrent.Executors;

import org.jinterop.dcom.common.JIException;
//import org.jinterop.dcom.core.JIVariant;
import org.openscada.opc.lib.common.ConnectionInformation;
import org.openscada.opc.lib.common.NotConnectedException;
import org.openscada.opc.lib.da.AccessBase;
import org.openscada.opc.lib.da.AddFailedException;
import org.openscada.opc.lib.da.AutoReconnectController;
import org.openscada.opc.lib.da.DataCallback;
import org.openscada.opc.lib.da.DuplicateGroupException;
import org.openscada.opc.lib.da.Item;
import org.openscada.opc.lib.da.ItemState;
import org.openscada.opc.lib.da.Server;
import org.openscada.opc.lib.da.SyncAccess;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;


public class opcClientSalem {
    public static void main(String[] args) throws Exception {
        // create connection information
        System.out.println("**********Initializing OPC Client**********");
        java.util.logging.Logger.getLogger("org.jinterop").setLevel(java.util.logging.Level.OFF);
        final ConnectionInformation ci = new ConnectionInformation("myusername","mypassword");
        ci.setHost("myhost");
        ci.setDomain("");
        ci.setProgId("Matrikon.OPC.Simulation.1");
        ci.setClsid("F8582CF2-88FB-11D0-B850-00C0F0104305");
        String itemIdArr[] = {"Random.Real8","Random.Int2"}; // This is where I would have an array of all items
        // create a new server
        final Server server = new Server(ci, Executors.newSingleThreadScheduledExecutor());
        AutoReconnectController controller = new AutoReconnectController(server);

        try {
            // connect to server
            System.out.println("**********Attempting to connect to OPC**********");
            controller.connect();
            System.out.println("**********Successfully connected to OPC**********");
            // add sync access, poll every 15000 ms
            final AccessBase access = new SyncAccess(server, 15000);

            while(true){
                for(final String str : itemIdArr){
                    access.addItem(str, new DataCallback() {
                        @Override
                        public void changed(Item item, ItemState state) {
                            // Building a JSON string with value recieved
                            String record = "[ {" +"\""+"name"+"\" :\""+str + "\",\""+"timestamp"+"\" :"+ state.getTimestamp().getTime().getTime()+ ",\""+"value"+"\" : "+value.replace("[", "").replace("]", "")  +",\"tags\":{\"test\":\"test1\"}} ]";

                            try {
                                // Post JSON string to my API which ingests this data
                                new opcClientSalem().restpost(record);
                            } catch (ClientProtocolException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }
                    });
                }
                // start reading
                access.bind();
                Thread.sleep(5000);
            }
            // wait a little bit

            // stop reading
            //access.unbind();
        } catch (final JIException e) {
            //System.out.println(String.format("%08X: %s", e.getErrorCode(), server.getErrorMessage(e.getErrorCode())));
        }
    }

    private void restpost(String record) throws ClientProtocolException, IOException{

        HttpClient client = new DefaultHttpClient();
        HttpPost post = new HttpPost("http://localhost/myapi/datapoints");
        StringEntity input = new StringEntity(record);
        post.setEntity(input);
        HttpResponse response = client.execute(post);
        System.out.println("Post success::"+record);
    }

}

I'm not sure you need to add the items over and over again in your while group. 我不确定您是否需要在while组中一遍又一遍地添加项目。

In other libraries (.net or native c++) usually you need to add the items only once, and the callback called whenever the value of the item is changed. 在其他库(.net或本机c ++)中,通常只需要添加一次,并且只要更改项的值就会调用回调。

In .net or c++ we get a global callback per group, which seems more effective than individual callbacks per items. 在.net或c ++中,我们每个组都有一个全局回调,这似乎比每个项目的单个回调更有效。 Maybe SyncAccess has some global callback, look for it. 也许SyncAccess有一些全局回调,寻找它。

So the possible optimizations: 因此可能的优化:

  • remove the while part, add items only once and sleep the thread infinite. 删除while部分,仅添加一次并无限线程休眠。
  • look for global callback for all items 寻找所有项目的全局回调

在这种情况下,您应该创建一个订阅。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM