Show pageOld revisionsBacklinksBack to top This page is read only. You can view the source, but not change it. Ask your administrator if you think this is wrong. Once you have the OPC Gateway running, it's possible access the OPC Legacy server from any system using pure Java code. Here's a sample that shows how to do that. <code java> import com.ergotech.util.SimulationManager; import com.ergotech.util.TargetLicenseManager; import com.ergotech.vib.exceptions.BadParameterException; import com.ergotech.vib.exceptions.VIBUpdateFailedException; import com.ergotech.vib.servers.SimpleDataSource; import com.ergotech.vib.servers.opc.opcclient.OPC; import com.ergotech.vib.utils.DataSourceContainer; import com.ergotech.vib.valueobjects.ValueChangedEvent; import com.ergotech.vib.valueobjects.ValueObjectInterface; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; public class OPCDemo { public static void main(String[] args) throws InterruptedException { OPCDemo opcDemo = new OPCDemo(); // Configure the license, required for OPC component to function. opcDemo.setupLicense(); // Disable simulation mode to connect to the actual OPC server. SimulationManager.getSimulationManager().setSimulating(false); // Initialize and start the OPC setup. opcDemo.setupOpc(); // Keep the application running for 5 minutes to receive updates from the OPC server. Thread.sleep(1000 * 60 * 5); } public void setupLicense() { try (InputStream license = Files.newInputStream(Path.of("resources/MIX.trg"))) { // Initialize the license manager with the appropriate target. final TargetLicenseManager manager = new TargetLicenseManager("MIX", license, OPCDemo.class.getClassLoader()); // Set the license manager for components. SimpleDataSource.setClassLicenseManager(manager); } catch (Exception e) { // Handle any failure during license setup. throw new RuntimeException("Failed to setup license", e); } } public void setupOpc() { DataSourceContainer container; try { // Create a new OPC container to hold the OPC components. container = DataSourceContainer.getRootContainer().createNewChildContainer("OPCExample"); } catch (BadParameterException e) { // Occurs if a container with the same name already exists. throw new RuntimeException("Failed to create OPC container", e); } OPC opc = new OPC(); try { // Assign a unique, case-insensitive name to the OPC component. opc.setName("OPC"); // Assign the host and item to connect to in the OPC server. opc.setHost("localhost"); // the host that is running the OPCGateway opc.setItem("GEMToolSimulator.VIDs.SVIDs.Temperature"); } catch (BadParameterException e) { // Handle invalid configuration for the OPC component. throw new RuntimeException("Invalid OPC configuration", e); } try { // Add the configured OPC component to the container. container.addComponent(opc, opc.getName()); } catch (BadParameterException e) { // Occurs if a component with the same name is already added to the container. throw new RuntimeException("Failed to add OPC component to container", e); } // Register a listener to handle value change events from the OPC server. opc.addValueChangedListener(new ValueChangedCallback()); try { // Initialize and start the OPC component. opc.init(); opc.start(); } catch (BadParameterException | VIBUpdateFailedException e) { // Handle any failure during initialization or startup. throw new RuntimeException("Failed to start OPC component", e); } // Access current values as various types // Force the server to register for value updates even though there are no listeners opc.setAutoSuspend(SimpleDataSource.AUTOSUSPEND_NEVER); // read the data System.out.println("Current value as String: " + opc.getValueObject().getStringValue()); System.out.println("Current value as Double: " + opc.getValueObject().getDoubleValue()); System.out.println("Current value as Float: " + opc.getValueObject().getFloatValue()); System.out.println("Current value as Integer: " + opc.getValueObject().getIntValue()); System.out.println("Current value as Long: " + opc.getValueObject().getLongValue()); System.out.println("Current value as Boolean: " + opc.getValueObject().getBoolValue()); } // Callback to process value changes from the OPC component. public static class ValueChangedCallback { // Any object with a method "valueInput(ValueChangedEvent) can be used a callback public void valueInput(ValueChangedEvent valueChangedEvent) { // Logic to handle changes in OPC data, triggered whenever the OPC value changes. ValueObjectInterface valueObject = valueChangedEvent.getValueObject(); System.out.println("Value Changed: " + valueObject + " [quality: " + valueObject.getQuality() + "]"); } } } </code> The OPC DA standard is optimized for a subscription model. Here's an example of reading multiple servers. Each will update when the value changes at the server and the updated value will be stored in a HashMap. Multiple listeners/HashMaps could be used to build "groups" of data, especially if you're looking to use ErgoTech's "TriggeredHistorical" component to periodically save these straight to a database. <code java> import com.ergotech.util.SimulationManager; import com.ergotech.util.TargetLicenseManager; import com.ergotech.vib.exceptions.BadParameterException; import com.ergotech.vib.exceptions.VIBUpdateFailedException; import com.ergotech.vib.servers.SimpleDataSource; import com.ergotech.vib.servers.opc.opcclient.OPC; import com.ergotech.vib.utils.DataSourceContainer; import com.ergotech.vib.valueobjects.ValueChangedEvent; import com.ergotech.vib.valueobjects.ValueObjectInterface; import java.io.InputStream; import java.nio.file.Files; import java.nio.file.Path; import java.util.HashMap; public class OPCDemo { // HashMap to store the latest values for each item private HashMap<String, ValueObjectInterface> itemValueMap = new HashMap<>(); public static void main(String[] args) throws InterruptedException { OPCDemo opcDemo = new OPCDemo(); // Configure the license, required for OPC component to function. opcDemo.setupLicense(); // Disable simulation mode to connect to the actual OPC server. SimulationManager.getSimulationManager().setSimulating(false); // Initialize and start the OPC setup. opcDemo.setupOpc(); // Keep the application running for 5 minutes to receive updates from the OPC server. Thread.sleep(1000 * 60 * 5); } public void setupLicense() { try (InputStream license = Files.newInputStream(Path.of("resources/MIX.trg"))) { // Initialize the license manager with the appropriate target. final TargetLicenseManager manager = new TargetLicenseManager("MIX", license, OPCDemo.class.getClassLoader()); // Set the license manager for components. SimpleDataSource.setClassLicenseManager(manager); } catch (Exception e) { // Handle any failure during license setup. throw new RuntimeException("Failed to setup license", e); } } public void setupOpc() { DataSourceContainer container; try { // Create a new OPC container to hold the OPC components. container = DataSourceContainer.getRootContainer().createNewChildContainer("OPCExample"); } catch (BadParameterException e) { // Occurs if a container with the same name already exists. throw new RuntimeException("Failed to create OPC container", e); } // List of items to monitor String[] items = { "GEMToolSimulator.VIDs.SVIDs.Temperature", "GEMToolSimulator.VIDs.SVIDs.Pressure", "GEMToolSimulator.VIDs.SVIDs.Humidity" }; // Create a single listener instance ValueChangedCallback listener = new ValueChangedCallback(); for (String item : items) { OPC opc = new OPC(); try { // Assign a unique, case-insensitive name to the OPC component. opc.setName("OPC_" + item); // Assign the host and item to connect to in the OPC server. opc.setHost("localhost"); // the host that is running the OPCGateway opc.setItem(item); } catch (BadParameterException e) { // Handle invalid configuration for the OPC component. throw new RuntimeException("Invalid OPC configuration", e); } try { // Add the configured OPC component to the container. container.addComponent(opc, opc.getName()); } catch (BadParameterException e) { // Occurs if a component with the same name is already added to the container. throw new RuntimeException("Failed to add OPC component to container", e); } // Register the same listener to handle value change events from the OPC server. opc.addValueChangedListener(listener); try { // Initialize and start the OPC component. opc.init(); opc.start(); } catch (BadParameterException | VIBUpdateFailedException e) { // Handle any failure during initialization or startup. throw new RuntimeException("Failed to start OPC component", e); } // Force the server to register for value updates even though there are no listeners opc.setAutoSuspend(SimpleDataSource.AUTOSUSPEND_NEVER); } // Access current values from the HashMap for (String item : items) { ValueObjectInterface valueObject = itemValueMap.get(item); if (valueObject != null) { System.out.println("Current value of " + item + " as String: " + valueObject.getStringValue()); System.out.println("Current value of " + item + " as Double: " + valueObject.getDoubleValue()); System.out.println("Current value of " + item + " as Float: " + valueObject.getFloatValue()); System.out.println("Current value of " + item + " as Integer: " + valueObject.getIntValue()); System.out.println("Current value of " + item + " as Long: " + valueObject.getLongValue()); System.out.println("Current value of " + item + " as Boolean: " + valueObject.getBoolValue()); } else { System.out.println("No value yet for " + item); } } } // Callback to process value changes from the OPC component. public class ValueChangedCallback { // Any object with a method "valueInput(ValueChangedEvent)" can be used as a callback public void valueInput(ValueChangedEvent valueChangedEvent) { // Logic to handle changes in OPC data, triggered whenever the OPC value changes. ValueObjectInterface valueObject = valueChangedEvent.getValueObject(); OPC opc = (OPC) valueChangedEvent.getSource(); String itemName = opc.getItem(); // Update the HashMap with the new value itemValueMap.put(itemName, valueObject); System.out.println("Value Changed for item " + itemName + ": " + valueObject + " [quality: " + valueObject.getQuality() + "]"); } } } </code> programmatic_sample_code.txt Last modified: 2024/10/15 10:28by wikiadmin