utgard OPC 主要功能簡介


度娘還行,盡管不好用,但所有的開發人員不懈努力地寫博客,能得到很多東西! 這里向所有未謀面的博主們致敬!

搜了一堆OPC資料,在這里整理一下,用一個封裝類來說明utgard的主要接口。使用了java自帶的觀察者模式,回調通知檢測點數據;

1. opc客戶端主類

public class OpcClient extends Observable {

  private Server mServer = null;

/**
* 連接opc server
*/
public synchronized boolean connectServer(String host, String progId, String user, String password, String domain) {
  boolean mState = false;
  ServerList serverList = null;
  try {
  // 獲取server上的opc server應用列表
  serverList = new ServerList(host, user, password, domain);

  // 連接server
  final ConnectionInformation connectionInfo = new ConnectionInformation();
  connectionInfo.setHost(host);
  connectionInfo.setClsid(serverList.getClsIdFromProgId(progId));// TODO 設置ProgId,無法連接server;設置Clsid,連接server成功
  connectionInfo.setUser(user);
  connectionInfo.setPassword(password);

  ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
  mServer = new Server(connectionInfo, executor);
  mServer.connect();

  mServer.addStateListener(new ServerConnectionStateListener() {
    @Override
    public void connectionStateChanged(boolean state) {
    System.out.println("connectionStateChanged state=" + state);
    }
  });

  mState = true;
} catch (IllegalArgumentException e) {
  e.printStackTrace();
} catch (UnknownHostException e) {
  e.printStackTrace();
} catch (JIException e) {
  e.printStackTrace();
} catch (AlreadyConnectedException e) {
  e.printStackTrace();
} finally {
  if (!mState) {
  mServer = null;
  }
}

return mState;
}

/**
* 斷開連接opc server
*/
public synchronized void disconnectServer() {
  if (mServer == null) {
  return;
  }
  mServer.disconnect();
  mServer = null;
}

/*
* 顯示server上的OPC服務器應用列表
*/
public void showAllOPCServer(String host, String user, String password, String domain) {
  try {
    ServerList serverList = new ServerList(host, user, password, domain);
    // 支持DA 1.0,DA 2.0規范
    Collection<ClassDetails> detailsList = serverList.listServersWithDetails(
    new Category[] { Categories.OPCDAServer10, Categories.OPCDAServer20 }, new Category[] {});
    for (final ClassDetails details : detailsList) {
      System.out.println("ClsId=" + details.getClsId() + " ProgId=" + details.getProgId() + " Description="
      + details.getDescription());
    }
  } catch (Exception e) {
    e.printStackTrace();
  }
}

/**
* 檢查opc server中是否包含指定的監測點列表
*/
public boolean checkItemList(List<String> list) {
  // 獲取opc server上的所有檢測點
  FlatBrowser flatBrowser = mServer.getFlatBrowser();
  if (flatBrowser == null) {
    return false;
  }

  try {
    Collection<String> collection = flatBrowser.browse();
    return collection.containsAll(list);
  } catch (Exception e) {
    e.printStackTrace();
  }
  return false;
}

/**
* 異步讀取數據 Async20Access實現了IOPCDataCallback接口,基於事件回調的實現
*/
public void asyncReadObject(final String itemId, int period) {
  // 第三個參數用於設置初始化時是否執行訪問
  AccessBase accessBase;
  try {
    accessBase = new Async20Access(mServer, period, false);
    accessBase.addItem(itemId, new DataCallback() {
    @Override
    public void changed(Item item, ItemState itemState) {
      System.out.println("asyncReadObject item=" + itemState);
      try {
        Object value = itemState.getValue().getObject();
        setData(itemId, value);
        } catch (JIException e) {
          e.printStackTrace();
        }
      }
    });
  // 開始讀取
  accessBase.bind();
  } catch (IllegalArgumentException e) {
    e.printStackTrace();
  } catch (UnknownHostException e) {
    e.printStackTrace();
  } catch (NotConnectedException e) {
    e.printStackTrace();
  } catch (JIException e) {
    e.printStackTrace();
  } catch (DuplicateGroupException e) {
    e.printStackTrace();
  } catch (AddFailedException e) {
    e.printStackTrace();
  }
}

/**
* 同步讀取數據
*/
public void syncReadObject(final String itemId, int period) {
  AccessBase accessBase;
  try {
    // SyncAccess會開啟一個線程,按照period時間間隔,定時去獲取監控點數據

    accessBase = new SyncAccess(mServer, period);

    //這個好像用處不太大
    accessBase.addStateListener(new AccessStateListener() {
      @Override
      public void stateChanged(boolean state) {
        System.out.println("stateChanged state=" + state);
      }

      @Override
      public void errorOccured(Throwable arg) {
      System.out.println("errorOccured arg=" + arg);
      }
    });

    accessBase.addItem(itemId, new DataCallback() {
      @Override
      public void changed(Item item, ItemState itemState) {
      System.out.println("syncReadObject item=" + itemState);
      if (itemState == null) {
        System.out.println("itemState is null");
        return;
      }


     try {
        Object value = itemState.getValue().getObject();
        setData(itemId, value);
      } catch (JIException e) {
        e.printStackTrace();
        }
      }
    });


  // 開始讀取
  accessBase.bind();
  // 解除綁定,停止讀取
  // accessBase.unbind();
  } catch (IllegalArgumentException e) {
    e.printStackTrace();
  } catch (UnknownHostException e) {
    e.printStackTrace();
  } catch (NotConnectedException e) {
    e.printStackTrace();
  } catch (JIException e) {
    e.printStackTrace();
  } catch (DuplicateGroupException e) {
    e.printStackTrace();
  } catch (AddFailedException e) {
    e.printStackTrace();
  }
}

/**
* 加入觀察者
*/
public void subscribe(Observer observer) {
  this.addObserver(observer);
}

/**
* 數據變化,通知觀察者
*/
private void setData(String itemId, Object value) {
  setChanged();
  notifyObservers(new Result(itemId, value));
  }
}

2. 檢測點數據Result.java

  public class Result {
    private String itemId;// 監控位置
    private Object value;// 監控值

    public Result(String itemId, Object value) {
      this.itemId = itemId;
      this.value = value;
    }

    public String getItemId() {
      return itemId;
    }

    public Object getValue() {
      return value;
    }

    @Override
    public String toString() {
      return "[itemId=" + itemId + ", value=" + value + "]";
    }
  }

測試:

public class Main {
  public static void main(String[] args) {
    String host = "127.0.0.1";// server
    String domain = "";// domain
    String progId = "ICONICS.SimulatorOPCDA.2";
    String user = "OpcUser";// server上的訪問用戶
    String password = "xxxxxx";// 訪問用戶的密碼

    OpcClient opcClient = new OpcClient();
    // 1.顯示server上的opc server應用列表
    opcClient.showAllOPCServer(host, user, password, domain);

    // 2.連接指定的opc server
    boolean ret = opcClient.connectServer(host, progId, user, password, domain);
    if (!ret) {
      System.out.println("connect opc server fail");
      return;
    }

    // 3.檢查opc server上的檢測點
    List<String> itemIdList = new ArrayList<String>();
    itemIdList.add("TEST.FA");
    itemIdList.add("TEST.FB");
    ret = opcClient.checkItemList(itemIdList);
    if (!ret) {
      System.out.println("not contain item list");
      return;
    }

    // 4.注冊回調
    opcClient.subscribe(new Observer() {
      @Override
      public void update(Observable observable, Object arg) {
      Result result = (Result) arg;
      System.out.println("update result=" + result);
      }
    });

    // 5.添加監聽檢測點的數據
    // client和server在不同網段,可以訪問
    opcClient.syncReadObject("TEST.FA", 500);
    /**
    * TODO 問題
    * client和server在不同網段,訪問失敗,比如:server為10.1.1.132,該網段下面又連接了擴展路由器,192.168.1.x,client為192.168.1.100
    */
    opcClient.asyncReadObject("TEST.FB", 500);

    // 延遲
    delay(5 * 60 * 1000);
   }

    private static void delay(long time) {
      try {
        Thread.sleep(time);
      } catch (InterruptedException e) {
        e.printStackTrace();
      }
    }
  }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM