2016-08-23 33 views
0

我已經使用Utgard OPC庫編寫了以下代碼。UTGARD opc客戶端:重複讀取多個項目

我需要每15秒從OPC服務器讀取一次數據。但是,我不確定這是否是實現它的最佳方式。在我的情況下,我需要從服務器上讀取300個標籤。

有什麼建議嗎?

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); 
    } 

} 
+1

你實際面臨什麼問題? –

+0

這段代碼運行得很好。我想知道是否有更好的方法來請求大量標籤而不是使用for循環。 –

回答

1

我不確定你需要在你的同時組中重複添加項目。

在其他庫(.net或本地C++)中,通常只需添加一次項目,並且在項目值改變時調用回調。

在.net或C++中,我們獲得了每個組的全局回調,這似乎比每個項目的單個回調更有效。也許SyncAccess有一些全局回調,請查找它。

所以可能的優化:

  • 去除部分的同時,添加項目只有一次,睡覺線程無限。
  • 尋找所有項目的全球回調
+0

我會嘗試你的建議,放棄while循環,看看事情是否仍然有效。 –

+0

我將while循環移至只執行thread.sleep(5000)。有用。謝謝。 –

0

您應該在這種情況下創建訂閱。

+0

您是否有任何關於如何設置訂閱的參考或代碼片段?我只使用OPC UA進行訂閱。 –

+0

我對您使用的庫一無所知,但SyncAccess可能實際上是在後臺創建訂閱。我不知道爲什麼你有一段時間(真)循環雖然... –

+0

我剛剛遇到AsyncAccess作爲替代SyncAccess。將試用它,讓你知道它是否解決了我的問題。 –