programmatic_sample_code

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
programmatic_sample_code [2024/10/14 14:30]
wikiadmin
programmatic_sample_code [2024/10/15 10:28] (current)
wikiadmin
Line 117: Line 117:
     }     }
  
 +}
 +</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> </code>
  • programmatic_sample_code.txt
  • Last modified: 2024/10/15 10:28
  • by wikiadmin