JAva opc clientオープンソースUtgard学習及びピット

8855 ワード

最近のプロジェクトではopc clientを運用する必要があります.opc serverからデータを取得したり、パラメータを変更したりする必要があります.主に使われる言語はjavaです.
準備知識:opc serverプロトコル
  • OPC DA:Data Accessプロトコルは、最も基本的なOPCプロトコルです.OPC DAサーバ自体はデータを格納せず,データ収集ポイントの現在値のみを表示する.クライアントはrefresh intervalを設定し、定期的にこの値をリフレッシュすることができます.現在一般的なプロトコルのバージョン番号は2.0と3.0で、2つのプロトコルは完全に互換性がありません.すなわち、OPC DA 2.0プロトコルを用いるクライアントは、OPC DA 3.0のサーバ
  • に接続できない.
  • OPC HDA:Historical Data Accessプロトコル.先に述べたようにDAは現在の状態値のみを表示し、データは格納しない.HDAプロトコルはデータベースによって提供され、履歴データへのアクセスを提供します.例えば高価なHistorianデータベースは、HDAプロトコルインタフェースを提供してOPCにアクセスする履歴データです.HDAのJavaクライアントは現在無料で見つかりません.
  • OPC UA:Unified Architecture統合アーキテクチャプロトコル.2008年に誕生し、従来のOPCプロトコルの煩雑さ、互いに互換性がないなどの劣勢を捨て、COM人のアクセスを必要とせず、プログラミングの難易度を大幅に簡素化した.OPC UAベースのオープンソースクライアントは非常に多い.しかし、誕生時間が遅いため、現在、国内の工業では大規模な応用がなく、このプロトコル自体が古いDAプロトコルと互換性がなく、クライアントは通用しない.

  • com:Component Object Modelオブジェクトコンポーネントモデルは、マイクロソフトが定義したソフトウェアのバイナリインタフェースであり、プログラミング言語にまたがるプロセス間通信を実現し、多重化を実現することができる.
    dcom:
    MicrosoftDistributed Component Object Modelは、ネットワークを介してデータを転送するCOMプロトコルであり、クライアントはインターネットを通じて隅々まで分散することができる.
     
    そして着工の準備をして、探してみると、2つのオープンソースクラスライブラリが存在します.
    1.JEasyOPC Client
    2.Utgard
    JEasyはjava呼び出し動的接続ライブラリであり,下位層はjni,dllライブラリが古い.
    Utgardは純java作成であり,opc 3.0プロトコルはサポートされていない.
    JEasyが呼び出すと、jniはいつもエラーを報告し、解決できません.
    最終的にUtgardのライブラリを使って、その公式サイトで使い方を学びましたhttp://openscada.org/projects/utgard/ああ、結局走り出しました.その中でopcサービス側の配置は、一般的なエンジニアが配置し、dcomの配置などの問題を心配する必要はありません.最終プロジェクトはmaven構成が完了しました.最終的に運行する時、1つのgroupが死んで発見できないことを発見して、私に新しく増加したと言って、しかしopcサービス端は再配置していないで、発見することができなくて、最後にやはりマニュアルを研究して、自分で手動で配置して完成しました.
    キーAPIの例
  • あるサーバの下のすべてのOPC接続
  • を列挙する
    ServerList serverList = new ServerList("10.1.5.123", "freud",
    		"password", "");
    
    Collection classDetails = serverList
    		.listServersWithDetails(new Category[] {
    				Categories.OPCDAServer10, Categories.OPCDAServer20,
    				Categories.OPCDAServer30 }, new Category[] {});
    
    for (ClassDetails cds : classDetails) {
    	System.out.println(cds.getProgId() + "=" + cds.getDescription());
    }
  • は、接続されたすべてのGroupおよびItem
  • を列挙する.
    public static void main(String[] args) throws Exception {
    	ConnectionInformation ci = new ConnectionInformation();
    	ci.setHost("10.1.5.123");
    	ci.setDomain("");
    	ci.setUser("freud");
    	ci.setPassword("password");
    	ci.setClsid("F8582CF2-88FB-11D0-B850-00C0F0104305");
    
    	Server server = new Server(ci, Executors.newSingleThreadScheduledExecutor());
    
    	server.connect();
    
    	dumpTree(server.getTreeBrowser().browse(), 0);
    	dumpFlat(server.getFlatBrowser());
    
    	server.disconnect();
    }
    
    private static void dumpFlat(final FlatBrowser browser)
    		throws IllegalArgumentException, UnknownHostException, JIException {
    	for (String name : browser.browse()) {
    		System.out.println(name);
    	}
    }
    
    private static void dumpTree(final Branch branch, final int level) {
    
    	for (final Leaf leaf : branch.getLeaves()) {
    		dumpLeaf(leaf, level);
    	}
    	for (final Branch subBranch : branch.getBranches()) {
    		dumpBranch(subBranch, level);
    		dumpTree(subBranch, level + 1);
    	}
    }
    
    private static String printTab(int level) {
    	StringBuilder sb = new StringBuilder();
    	for (int i = 0; i < level; i++) {
    		sb.append("\t");
    	}
    	return sb.toString();
    }
    
    private static void dumpLeaf(final Leaf leaf, final int level) {
    	System.out.println(printTab(level) + "Leaf: " + leaf.getName() + ":"
    			+ leaf.getItemId());
    }
    
    private static void dumpBranch(final Branch branch, final int level) {
    	System.out.println(printTab(level) + "Branch: " + branch.getName());
    }
  • Itemの同期クエリ
  • public static void main(String[] args) throws Exception {
    
    	ConnectionInformation ci = new ConnectionInformation();
    	ci.setHost("10.1.5.123");
    	ci.setDomain("");
    	ci.setUser("freud");
    	ci.setPassword("password");
    	ci.setClsid("F8582CF2-88FB-11D0-B850-00C0F0104305");
    
    	Server server = new Server(ci,
    			Executors.newSingleThreadScheduledExecutor());
    
    	server.connect();
    
    	Group group = server.addGroup();
    	Item item = group.addItem("Random.Real5");
    
    	Map items = group.addItems("Random.Real1",
    			"Random.Real2", "Random.Real3", "Random.Real4");
    
    	dumpItem(item);
    
    	for (Entry temp : items.entrySet()) {
    		dumpItem(temp.getValue());
    	}
    
    	server.dispose();
    }
    
    private static void dumpItem(Item item) throws JIException {
    	System.out.println("[" + (++count) + "],ItemName:[" + item.getId()
    			+ "],value:" + item.read(false).getValue());
    }
    
    private static int count;
  • Itemの非同期クエリ
  • private static final int PERIOD = 100;
    
    private static final int SLEEP = 2000;
    
    public static void main(String[] args) throws Exception {
    
    	ConnectionInformation ci = new ConnectionInformation();
    	ci.setHost("10.1.5.123");
    	ci.setDomain("");
    	ci.setUser("freud");
    	ci.setPassword("password");
    	ci.setClsid("F8582CF2-88FB-11D0-B850-00C0F0104305");
    
    	Server server = new Server(ci,
    			Executors.newSingleThreadScheduledExecutor());
    
    	server.connect();
    
    	AccessBase access = new SyncAccess(server, PERIOD);
    
    	access.addItem("Random.Real5", new DataCallback() {
    		private int i;
    
    		public void changed(Item item, ItemState itemstate) {
    			System.out.println("[" + (++i) + "],ItemName:[" + item.getId()
    					+ "],value:" + itemstate.getValue());
    		}
    	});
    
    	access.bind();
    	Thread.sleep(SLEEP);
    	access.unbind();
    	server.dispose();
    }
  • Itemのパブリケーション購読クエリー
  • private static final int PERIOD = 100;
    
    private static final int SLEEP = 2000;
    
    public static void main(String[] args) throws Exception {
    
    	ConnectionInformation ci = new ConnectionInformation();
    	ci.setHost("10.1.5.123");
    	ci.setDomain("");
    	ci.setUser("freud");
    	ci.setPassword("password");
    	ci.setClsid("F8582CF2-88FB-11D0-B850-00C0F0104305");
    
    	Server server = new Server(ci,
    			Executors.newSingleThreadScheduledExecutor());
    
    	server.connect();
    
    	AccessBase access = new Async20Access(server, PERIOD, false);
    
    	access.addItem("Random.Real5", new DataCallback() {
    
    		private int count;
    
    		public void changed(Item item, ItemState itemstate) {
    			System.out.println("[" + (++count) + "],ItemName:["
    					+ item.getId() + "],value:" + itemstate.getValue());
    		}
    	});
    
    	access.bind();
    	Thread.sleep(SLEEP);
    	access.unbind();
    	server.dispose();
    }
  • 自動再接続Item非同期読み出し
  • private static final int PERIOD = 100;
    
    private static final int SLEEP = 2000;
    
    public static void main(String[] args) throws Exception {
    
    	ConnectionInformation ci = new ConnectionInformation();
    	ci.setHost("10.1.5.123");
    	ci.setDomain("");
    	ci.setUser("freud");
    	ci.setPassword("password");
    	ci.setClsid("F8582CF2-88FB-11D0-B850-00C0F0104305");
    
    	Server server = new Server(ci,
    			Executors.newSingleThreadScheduledExecutor());
    
    	AutoReconnectController controller = new AutoReconnectController(server);
    
    	controller.connect();
    
    	AccessBase access = new SyncAccess(server, PERIOD);
    
    	access.addItem("Random.Real5", new DataCallback() {
    		private int i;
    
    		public void changed(Item item, ItemState itemstate) {
    			System.out.println("[" + (++i) + "],ItemName:[" + item.getId()
    					+ "],value:" + itemstate.getValue());
    		}
    	});
    
    	access.bind();
    	Thread.sleep(SLEEP);
    	access.unbind();
    	controller.disconnect();
    }
  • Item同期書き込み
  • public static void main(String[] args) throws Exception {
    
    	ConnectionInformation ci = new ConnectionInformation();
    	ci.setHost("10.1.5.123");
    	ci.setDomain("");
    	ci.setUser("freud");
    	ci.setPassword("password");
    	ci.setClsid("F8582CF2-88FB-11D0-B850-00C0F0104305");
    
    	Server server = new Server(ci,
    			Executors.newSingleThreadScheduledExecutor());
    
    	server.connect();
    
    	Group group = server.addGroup();
    	Item item = group.addItem("Square Waves.Real4");
    
    	final Float[] integerData = new Float[] { 1202f, 1203f, 1204f };
    	final JIArray array = new JIArray(integerData, false);
    	final JIVariant value = new JIVariant(array);
    
    	item.write(value);
    	Thread.sleep(2000);
    
    	dumpItem(item);
    
    	server.dispose();
    
    }
    
    private static void dumpItem(Item item) throws JIException {
    	System.out.println("[" + (++count) + "],ItemName:[" + item.getId()
    			+ "],value:" + item.read(true).getValue());
    }
    
    private static int count;
  • Item非同期書き込み
  •  
    参考資料
    Matrikon公式サイト: http://www.matrikonopc.cn/downloads/drivers-index.aspx