Jade应用opc服务器的数据展示

流程:
建立数据--->Agent读取opc数据--->组建MAS,Agent之间传递数据--->接收数据的远程Agent表格形式显示数据。
遇到的问题

  1. Exception in thread "main" java.lang.UnsatisfiedLinkError: Directory separator should not appear in library name: ./lib/JCustomOpc
    我沿着提示去弄悲剧了,用的是mac,要为自己的土豪和下载的时候没注意看买单了,JEasyOpc只能用windows系统,下载页面有提示。[DownLoad]
    Java Easy OPC client. The client is based on Java technology. The core library is created in Delphi (only for OS Windows).
  2. opcserver和跑的代码不在一个机子,The connection to xxx has failed
    要配置DCOM好像,我也没弄,挺复杂的,搞工控的人比较懂,所以opc服务器,读opc数据的agent和接收数据并画出图的agent都在本地
    [DownLoad]:https://sourceforge.net/projects/jeasyopc/
    一. 建立OPC模拟数据(MatrikonOPC Explorer)
  3. 打开桌面应用,连接,建立group,加入item,使用生成器(item页面的item ID右侧图标),命名格式要符合系统默认,比如Bucket Brigade.xxx和Random.xxx等。选Bucket Brigade
  4. 让数据在一定范围内递增递减变化,选择item,右键write value,选择信号生成器,(a)设定上下限,上限要大于下限,增量可以正负,(b)点击Apply,(c)点击start。没发现范围内随变的设置方法。一次只能一个,窗口关闭就停止变化。或者把频率调成100,然后过会关闭,会一直把缓存输出完才停止。

二. 代码示例

  1. Jeasyopc库导入
  • 首先在src下新建包javafish.clients.opc 将JCustomOpc.properties 拷贝到包中, 然后导入三个jar包jeasyopc.jar commons-logging-1.1.jar和log4j-1.2.13.jar
  • 在项目下新建一个lib目录,也可以自定义名字和路径,但是在JCustomOpc.properties 配置中能指定这个目录。将JCustomOpc.dll拷贝到 你定义好的目录下。
  • resource文件夹拉倒src目录下(eclipse没找到导入文件夹的方式,可以用直接拖拽的方式)
  1. jade库导入
  • 导入jade.jar,现在的版本只要这个jar包,已经集成到这个包了,网上的好多个都已经没有了
  • eclipse下运行代码,右键代码文件,run as - run configuration ,
    跳出的页面 Name 添文件名,Main class 填jade.Boot,点击(x)=Arguments 选项卡,program arguments填 -agents agent的名字:包名1.包名2.类名(这步为jade做得,纯java不用)
    包名个数根据实际情况,可能没有包名,示例-agents h1:use.RepeatReceive
  1. java 读写opc数据
  • 中文乱码没解决,不过实际过程一般都是数字和英文字符
package examples;
import javafish.clients.opc.JOpc;
import javafish.clients.opc.component.OpcGroup;
import javafish.clients.opc.component.OpcItem;
import javafish.clients.opc.exception.ComponentNotFoundException;
import javafish.clients.opc.exception.ConnectivityException;
import javafish.clients.opc.exception.SynchReadException;
import javafish.clients.opc.exception.SynchWriteException;
import javafish.clients.opc.exception.UnableAddGroupException;
import javafish.clients.opc.exception.UnableAddItemException;
import javafish.clients.opc.exception.UnableRemoveGroupException;
import javafish.clients.opc.exception.UnableRemoveItemException;
import javafish.clients.opc.variant.Variant;
import sun.management.HotspotThreadMBean;

public class TestReadWrite {

    public static void main(String[] args) throws ConnectivityException, ComponentNotFoundException,
            UnableAddGroupException, UnableAddItemException, SynchReadException, UnableRemoveItemException,
            UnableRemoveGroupException, SynchWriteException, InterruptedException {
        // 第一步,初始化
        // 把配置文件javafish/clients/opc/JCustomOpc.properties、放到classpath
        JOpc.coInitialize();
        // 第二步,建立一个JOpc对象,三个参数,分别是OpcServer的IP,Server的name,还有JOpc的name
        JOpc jopc = new JOpc("local", "Matrikon.OPC.Simulation.1", "JOPC1");
        // 第三步,建立连接
        jopc.connect();
        // 第四步,新建一个OPC的group和item,并把item加到group中
        OpcGroup group = new OpcGroup("Group0", true, 1000, 0.0f);
        OpcItem item = new OpcItem("Bucket Brigade.temp1", true, "");
        group.addItem(item);
        // 第五步,注册group,item
        jopc.addGroup(group);
        jopc.registerGroup(group);
        jopc.registerItem(group, item);
        // 读
        OpcItem responseItem, responseItem2;
        responseItem = jopc.synchReadItem(group, item);
        System.out.println("responseItem = " + responseItem.getValue());
        // 第六步赋值,并同步至服务器
        item.setValue(new Variant(24));
        jopc.synchWriteItem(group, item);
        // 等待1秒,写完太快读,读不到新值
        Thread thread = Thread.currentThread();
        thread.sleep(1000);
        responseItem2 = jopc.synchReadItem(group, item);
        System.out.println("responseItem = " + responseItem2.getValue());

        // 最后,该释放的全释放掉
        jopc.unregisterItem(group, item);
        jopc.unregisterGroup(group);
        JOpc.coUninitialize();
    }
}

4.jade代码

  • 数据要重复传输,本来可以用他的循环行为,但是有很多数据的使用变复杂了,比如内部类,外部数据用final才能传进来,然后又不能修改等,所以就用while方法了。
//BeReceive.java,(x)=Arguments 选项卡 -container -host localhost -agents h1:use.RepeatReceive
package use;
import com.sun.corba.se.spi.oa.OADestroyed;
import jade.core.AID;
import jade.core.Agent;
import jade.lang.acl.ACLMessage;
import javafish.clients.opc.JOpc;
import javafish.clients.opc.component.OpcGroup;
import javafish.clients.opc.component.OpcItem;
import javafish.clients.opc.exception.ComponentNotFoundException;
import javafish.clients.opc.exception.ConnectivityException;
import javafish.clients.opc.exception.SynchReadException;
import javafish.clients.opc.exception.UnableAddGroupException;
import javafish.clients.opc.exception.UnableAddItemException;
import javafish.clients.opc.exception.UnableRemoveGroupException;
import javafish.clients.opc.exception.UnableRemoveItemException;

public class BeReceive extends Agent{
    public void setup(){
        // 第一步,初始化
                // 把配置文件javafish/clients/opc/JCustomOpc.properties、放到classpath
                JOpc.coInitialize();
                // 第二步,建立一个JOpc对象,三个参数,分别是OpcServer的IP,Server的name,还有JOpc的name
                JOpc jopc = new JOpc("local", "Matrikon.OPC.Simulation.1", "JOPC1");
                // 第三步,建立连接
                try {
                    jopc.connect();
                } catch (ConnectivityException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                // 第四步,新建一个OPC的group和item,并把item加到group中
//              OpcGroup group = new OpcGroup("TestGroup", true, 1000, 0.0f);
//              OpcItem item = new OpcItem("Bucket Brigade.Int1", true, "");
                OpcGroup group = new OpcGroup("Group0", true, 1000, 0.0f);
                int N = 5;
                OpcItem[] items = new OpcItem[N];
                OpcItem[] responseItems = new OpcItem[N];
                for(int i = 0; i < N; i++){
                    items[i] = new OpcItem("Bucket Brigade.temp"+(i+1), true, "");
                    group.addItem(items[i]);
                }
                //items[0] = new OpcItem("Bucket Brigade.temp1", true, "");
                //items[1] = new OpcItem("Bucket Brigade.temp2", true, "");
                //group.addItem(items[0]);
                //group.addItem(items[1]);
                // 第五步,注册group,item
                jopc.addGroup(group);
                try {
                    jopc.registerGroup(group);
                } catch (ComponentNotFoundException | UnableAddGroupException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                try {
                    for(int i = 0; i < N; i++)
                    jopc.registerItem(group, items[i]);
                    
                } catch (ComponentNotFoundException | UnableAddItemException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                // 读
                for(int i = 0; i < N; i++)
                responseItems[i] = new OpcItem("", true, "");
                //System.out.println(responseItem.getValue());
                String oldstr ="";
                Boolean flag = true;
                while(flag){
                // 第六步继续读
                    Thread thread = Thread.currentThread();
                    try {
                        thread.sleep(1000);
                    } catch (InterruptedException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                    try {
                        for(int i = 0; i < N; i++)
                        responseItems[i] = jopc.synchReadItem(group, items[i]);

                    } catch (ComponentNotFoundException | SynchReadException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }
                    
                    StringBuilder sb = new StringBuilder();
                    for(int i = 0; i < N; i++)
                        sb.append(responseItems[i].getValue()+" ");
                    System.out.println(sb.toString());
                    if(oldstr.equals(sb.toString()))
                        continue;
                    oldstr = sb.toString();
                    System.out.println(oldstr+"11");
                    ACLMessage message = new ACLMessage(ACLMessage.INFORM);
                    message.addReceiver(new AID("h2",AID.ISLOCALNAME));//接收端的agent名字要对,这里用h2
                    //message.setLanguage("English");
                    message.setOntology("温度/℃ 湿度/%rh 压强/kPa 体积/m³ 流速/m/s");
                    System.out.println("温度/℃ 湿度/%rh 压强/kPa 体积/m³ 流速/m/s".split(" ").length);
                    System.out.println(oldstr.split(" ").length);
                    message.setContent(oldstr);
                    send(message);
                    
                    
                }
                    // 最后,该释放的全释放掉
                try {
                    for(int i = 0; i < N; i++)
                    jopc.unregisterItem(group, items[i]);
                } catch (ComponentNotFoundException | UnableRemoveItemException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                try {
                    jopc.unregisterGroup(group);
                } catch (ComponentNotFoundException | UnableRemoveGroupException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                JOpc.coUninitialize();
        }
    }
//OpAgent.java  (x)=Arguments 选项卡 -gui -agents h2:use. OpAgent

package use;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

import jade.core.Agent;
import jade.core.behaviours.SimpleBehaviour;
import jade.lang.acl.ACLMessage;
public class OpAgent extends Agent {
    public void setup() {
        addBehaviour(new SimpleBehaviour(this) {

            @Override
            public boolean done() {
                // TODO Auto-generated method stub
                return false;
            }

            @Override
            public void action() {
                // TODO Auto-generated method stub
                ACLMessage message = myAgent.receive();
                if (message != null) {
                    String str1 = message.getContent();
                    String str2 = message.getOntology();
                    String[] name = str2.split(" ");
                    String[] value = str1.split(" ");
                    int len = name.length;
                    JTable table = null;
                    DefaultTableModel defaultModel = null;
                    JFrame frame = new JFrame();
                    //String[] name2 = str2.split(" "); // { "温度/℃", "湿度%rh",
                                                        // "压强/kPa", "体积/m³",
                                                        // "流量/m³" };
                    String[][] data = new String[1][len];
                    for (int j = 0; j < len; j++) {
                        String k = value[j];
                        String dString = data[0][j];
                        
                        //data[0][j] = value[j];
                    }

                    defaultModel = new DefaultTableModel(data, name);// 加入數據和字段名構造tablemodel
                    table = new JTable(defaultModel);// 設置表格模式為DefaultTableModel
                    table.setPreferredScrollableViewportSize(new Dimension(300, 80));
                    table.setShowVerticalLines(false);
                    table.setShowVerticalLines(true);
                    JScrollPane s = new JScrollPane(table);

                    Container contentPane = frame.getContentPane();
                    contentPane.add(s, BorderLayout.SOUTH);

                    frame.setTitle("数据监控");
                    frame.pack();
                    frame.setVisible(true);

                    while (true) {
                        //System.out.println("in while");
                        ACLMessage m = myAgent.receive();
                        if (m != null) {
                             str1 = m.getContent();
                             value = str1.split(" ");
                             for(int i = 0; i < len; i++)
                            defaultModel.setValueAt(value[i], 0, i);
                        } else {
                            block();
                        }
                        defaultModel.fireTableDataChanged();
                    }

                } else
                    block();

            }
        });
    }

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容