# The script not neccessarily should have a function.
# Input data is available via variable "inputArgument"

# Global variable "result" must be declared
# Then resulting value must be assigned to the global variable "result"
global result

def filter(arg):
    # Single argument "arg" is a JSON formatted string. 
        # The member "Server" has information about OPC UA server.
        # The member "Parent" defines what node is being browsed, that is, what node the variables belong to.
        # Its member "Nodes" is array of JSON objects, each representing OPC UA Variable.
            # The member of boolean type "Selected" defines, wither the varible is logged or not. 
            # The purpose of the script is to modify value of the "Selected" member accordingly. You can also modify logging options such as SamplingInterval, DeadbandValue, etc.
    
            # This array must be returned by the script.
            
        # The "arg" has also other data, for 
        # Complete structure of data passed to the function can be viewed in Browser Log file. 
    
    # The "globalVariables" is a dictionary, persisted between sequential calls, where data can be stored at runtime.
    # For example, it can be used to track total number of variables selected (see the variable "totalVars" below).
    global globalVariables

    totalVars = 0
    index = 0

    # In Community Edition the number of variables after 1 month becomes limited to 64. For 1 month after activation, there is no limit.
    maxVariables = 64
    
    if "totalVariables" in globalVariables:
        totalVars = int(globalVariables["totalVariables"])

    try:
        inputData = json.loads(arg)
        nodes = inputData["Nodes"]
        numberOfRecords = len(nodes)
        # print ("Parent = {0}, Depth = {1}".format(inputData["Parent"], inputData["Depth"]))
        
        # Iterate over variable nodes and set member "Selected". If "Selected" is True, the variable is logged, otherwise not logged.
        while index < numberOfRecords:
            node = nodes[index]
            nodeId = node["NodeId"]
            browsePath = node["BrowsePath"]
            ns = nodeId["Namespace"]
            
            # Skip all standard nodes (with namespace index 0):
            if ns == 0:
                node["Selected"] = False
            else:
                node["Selected"] = True
                # Select variables depending of the node attributes.
                # For example, to select variables of Air Conditioners and Furnace in the Unified Automation OPC UA Demo Server:
                if re.search('AirConditioner', browsePath) or re.search('Furnace', browsePath):
                    node["Selected"] = True
                else:
                    node["Selected"] = False

            if node["Selected"] == True:
                if totalVars >= maxVariables:
                    node["Selected"] = False
                    # Keep going, need to set selection flag to false for the rest of variables.
                else:
                    totalVars = totalVars + 1
                    
            # Other logging configuration settings can be adjusted too:
            # node["PublishingInterval"] = 1000
            # node["SamplingInterval"] = 500
            
            index = index + 1
            
            # Complex type variables can have child nodes, that can be browsed down or not, depending on the boolean member "BrowseMembers":
            # You can log only leave variable nodes without logging of a complete variable, or log only whole value, or log all.
            node["BrowseMembers"] = True
            
        # Update entry in the global variables for total number of variables: 
        globalVariables["totalVariables"] = str(totalVars)

        # Printing can be uncommented for debugging, it will go the the application console output.
        # print("Processed {} variable nodes, total number of variables = {}".format(index, totalVars))
        return nodes

    except:
        print('Exception occurred in the function "filter" used to discover variables.')
        pass
    
        return []
# Resulting value must be assigned to the global variable "result"        
result = filter(inputArgument)


