package com.eas.opc.hda; import com.eas.opc.OPCCommon; import com.eas.opc.da.dcom.FileTime; import com.eas.opc.da.dcom.ResultTable; import com.eas.opc.hda.dcom.IOPCHDA_Server; import com.eas.opc.hda.dcom.IOPCHDA_SyncRead; import com.eas.opc.hda.dcom.OPCHDA_ITEM; import com.eas.opc.hda.dcom.OPCHDA_TIME; import java.net.UnknownHostException; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import org.jinterop.dcom.common.JIException; /* * To change this template, choose Tools | Templates * and open the template in the editor. */ /** * * @author pk */ public class OPCHDAServerConnection extends OPCCommon { protected IOPCHDA_Server opchdaServer; private final List<HistoryItem> knownItems = new ArrayList<>(); private IOPCHDA_SyncRead syncRead; @Override public void connect(String progID, String domain, String hostname, String username, String password) throws JIException, UnknownHostException { super.connect(progID, domain, hostname, username, password); this.opchdaServer = new IOPCHDA_Server(opcCommon.queryInterface(IOPCHDA_Server.IID_IOPCHDA_Server)); this.syncRead = new IOPCHDA_SyncRead(opcCommon.queryInterface(IOPCHDA_SyncRead.IID_IOPCHDA_SyncRead)); } @Override public void disconnect() { cleanup(); opchdaServer = null; syncRead = null; super.disconnect(); } public int[] addItems(HistoryItem... items) throws JIException { final String[] itemIDs = new String[items.length]; final Integer[] clientHandles = new Integer[items.length]; synchronized (this) { for (int i = 0; i < items.length; i++) { if (knownItems.contains(items[i])) { throw new IllegalArgumentException(String.format("Item %s is already added.", items[i].getItemID())); } itemIDs[i] = items[i].getItemID(); clientHandles[i] = items[i].getClientHandle(); } } final ResultTable<Integer, Integer> r = opchdaServer.getItemHandles(itemIDs, clientHandles); final int[] errors = new int[items.length]; synchronized (this) { for (int i = 0; i < items.length; i++) { errors[i] = r.errorCode(items[i].getClientHandle()); items[i].setServerHandle(r.get(items[i].getClientHandle())); if (errors[i] == 0 /* S_OK */) { knownItems.add(items[i]); } } } return errors; } public int[] removeItems(HistoryItem... items) throws JIException { final Integer[] serverHandles = new Integer[items.length]; synchronized (this) { for (int i = 0; i < items.length; i++) { if (!knownItems.contains(items[i]) || items[i].getServerHandle() == null) { throw new IllegalArgumentException(String.format("Item %s is not added.", items[i].getItemID())); } serverHandles[i] = items[i].getServerHandle(); } } final ResultTable<Integer, Void> r = opchdaServer.releaseItemHandles(serverHandles); final int[] errors = new int[items.length]; synchronized (this) { for (int i = 0; i < items.length; i++) { errors[i] = r.errorCode(items[i].getServerHandle()); knownItems.remove(items[i]); } } return errors; } public HistoryItem.History[] readRaw(Date startTime, Date endTime, int numValues, boolean withBounds, HistoryItem... items) throws JIException { final OPCHDA_TIME sTime = new OPCHDA_TIME(false, "", new FileTime(startTime)), eTime = new OPCHDA_TIME(false, "", new FileTime(endTime)); final Integer[] serverHandles = new Integer[items.length]; synchronized (this) { for (int i = 0; i < items.length; i++) { if (!knownItems.contains(items[i]) || items[i].getServerHandle() == null) { throw new IllegalArgumentException(String.format("Item %s is not added.", items[i].getItemID())); } serverHandles[i] = items[i].getServerHandle(); } } final IOPCHDA_SyncRead.ReadResult<OPCHDA_ITEM> r = syncRead.readRaw(sTime, eTime, numValues, withBounds, serverHandles); final HistoryItem.History[] histories = new HistoryItem.History[items.length]; for (int i = 0; i < items.length; i++) { final OPCHDA_ITEM results = r.getResults().get(items[i].getServerHandle()); final Date hStartTime = r.getStartTime().getTime().getTime(); final Date hEndTime = r.getEndTime().getTime().getTime(); final int aggregate = results.getAggregate(); if (results.getClientHandle() == items[i].getClientHandle()) { final HistoryItem.History.Record[] records = new HistoryItem.History.Record[results.getCount()]; for (int j = 0; j < records.length; j++) { records[j] = new HistoryItem.History.Record(results.getTimeStamps()[j].getTime(), results.getQualities()[j], results.getValues()[j]); } histories[i] = new HistoryItem.History(hStartTime, hEndTime, items[i], aggregate, records); } else { Logger.getLogger(OPCHDAServerConnection.class.getName()).log(Level.WARNING, "OPCHDA_ITEM itemClientHandle={0}, OPCHDA_ITEM clientHandle={1}, serverHandle={2} at {3}", new Object[]{items[i].getClientHandle(), results.getClientHandle(), items[i].getServerHandle(), i}); } } return histories; } public HistoryItem.History[] readRaw(Date startTime, Date endTime, int numValues, boolean withBounds) throws JIException { HistoryItem[] items; synchronized (this) { items = new HistoryItem[knownItems.size()]; items = knownItems.toArray(items); } return readRaw(startTime, endTime, numValues, withBounds, items); } protected void cleanup() { synchronized (this) { HistoryItem[] items = new HistoryItem[knownItems.size()]; items = knownItems.toArray(items); try { removeItems(items); } catch (JIException ex) { Logger.getLogger(OPCHDAServerConnection.class.getName()).log(Level.SEVERE, "error removing items on cleanup.", ex); } knownItems.clear(); } } }