OPCItemLoader.g

OPCItemLoader.g — reads a list of OPC tags from a CSV file and configures DataHub points for them.

Code

[Note]

The code for this and other example scripts can be found in the DataHub distribution archive, typically at one of these locations:

    C:\Program Files\Cogent\OPC DataHub\scripts\

    C:\Program Files\Cogent\Cascade DataHub\scripts\

Please refer to Section 3.1, “How to Run a Script” for more information on using scripts.

/* This script reads a set of OPC item names and point names from a CSV file and updates
 * the Manually Selected Items configuration for an OPC connection.  The CSV file format can
 * be one of:
 *     OPC_ITEM_ID
 * or
 *     OPC_ITEM_ID, OPC_DATAHUB_POINT_NAME
 *
 * If the OPC_DATAHUB_POINT_NAME is absent (the line contains only an OPC item ID), then the
 * script will create an OPC DataHub point with the same name as the OPC item ID.  The OPC item
 * ID is the item ID defined by the OPC server.
 *
 * To use this script, follow these steps:
 * 
 * 1) Create the OPC connection that you want to add items to.  Select "Manually Select Items"
 *    only in the "Item Selection" section.  You do not need to configure any items.  Press
 *    OK to save the OPC configuration, the press Apply on the OPC DataHub properties dialog.
 * 2) Open this script in the editor and change the parameters in the OPCItemLoader class
 *    definition.  These are documented below.
 * 3) Close the OPC DataHub Properties window.
 * 4) Run this script by pressing the run button in the toolbar of the editor (the right-facing
 *    blue arrow).
 * 5) Open the OPC DataHub properties dialog, open the OPC configuration for your server and
 *    verify that the items were added.
 *
 * If the script has problems, you should see error messages in the "Script Log" window.
 *
 * You must close the OPC DataHub Properties window before running this script or the
 * changes made by this script may be lost.
 *
 * You do not need to run this script each time the OPC DataHub is started.  The configuration
 * produced by this script will be saved in the OPC DataHub's configuration file permanently.
 *
 * Editable fields:
 *   connection_name = the name of the OPC connection to be adjusted.  This is the name
 *		entered into the box marked "Connection Name:" in the "Define OPC Server" dialog
 *		of the OPC DataHub properties dialog.
 *   file_name = the file name containing the OPC item names and point names.  The file
 *		can either either one or two strings per line separated by commas.  If only a single
 *		string appears, it is taken to be the OPC server item name.  The point name is
 *		computed from the item name.  If two strings appear then the first string is the
 *		OPC item and the second string is the OPC DataHub point name.  The point name will
 *		automatically be broken into components on a "." and a tree hierarchy will be
 *		created as if each component but the last is a tree branch.
 *   trim_spaces = t if you want the item and point names to be trimmed of all leading and
 *		trailing white space and tabs, otherwise nil.
 *   path_separator = nil if you do not want to split point names to produce a tree
 *		hierarchy, otherwise a string containing separator characters.  Normally this will
 *		be a "." character.
 */

require ("Application");
require ("WindowsSupport");
require ("OPCSupport");

class OPCItemLoader Application
{
    connection_name = "OPC000";	// Change this to the connection name of the connection to edit
    file_name = "my_items.csv";	// Change this to the file containing the item and point names
    trim_spaces = t;            // set to nil to preserve leading and trailing spaces in item names
    path_separator = ".";       // Characters used to split point names into tree components
    file_is_8bit_ansi = t;      // Set to t if file uses 8-bit extended ANSI, nil if 7-bit ASCII or UTF-8
    opc_connection;
}

method OPCItemLoader.Trim (str)
{
    local	i=0, j, len;
    len = strlen(str);
    while (i < len && (str[i] == ' ' || str[i] == '\t'))
        i++;

    j = len - 1;
    while (j >= i && (str[j] == ' ' || str[j] == '\t'))
        j--;
	
    if (j>=i)
        str = substr(str, i, j-i+1);
    else
        str = "";
    str;
}

method OPCItemLoader.ReadCSVFile (filename)
{
    local		fptr = open (filename, "r", nil);
    local		line, i;
    if (fptr)
    {
        while ((line = read_line(fptr)) != _eof_)
        {
            if (.file_is_8bit_ansi)
                line = strcvt(line);
                
            if (line != "")
            {
                line = list_to_array(string_split(line, ",", 0, nil, nil, nil, "\\", nil));
                if (.trim_spaces)
                {
                    for (i=0; i<length(line); i++)
                    {
                        line[i] = .Trim(line[i]);
                    }
                }
                if (length(line) == 1)
                    .AddOPCItem(line[0], line[0]);
                else if (length(line) > 1)
                    .AddOPCItem(line[0], line[1]);
            }
        }
        close (fptr);
    }
    else
    {
        local s = strerror(errno());
        princ (class_name(self), ": Could not open file: ", filename, ": ", s, "\n");
    }
}

method OPCItemLoader.AddOPCItem(itemname, pointname)
{
    .opc_connection.addItem(pointname, itemname, OPC_NODE_LEAF, .path_separator);
}

method OPCItemLoader.LoadFromCSV(opc_conn_name, filename)
{
    local opc = new OPCConnection();
    opc.setServer(opc_conn_name);
    .opc_connection = opc;
    .ReadCSVFile(filename);
}

/* Write the 'main line' of the program here. */
method OPCItemLoader.constructor ()
{
    .LoadFromCSV(.connection_name, .file_name);
}

/* Any code to be run when the program gets shut down. */
method OPCItemLoader.destructor ()
{
}

ApplicationSingleton (OPCItemLoader);