Please Note This forum exists for community support for the Mango product family and the Radix IoT Platform. Although Radix IoT employees participate in this forum from time to time, there is no guarantee of a response to anything posted here, nor can Radix IoT, LLC guarantee the accuracy of any information expressed or conveyed. Specific project questions from customers with active support contracts are asked to send requests to support@radixiot.com.

Radix IoT Website Mango 3 Documentation Website Mango 4 Documentation Website

  • I had this script working:

    function AutoThrottle2( xid )
    {
        var source = DataSourceQuery.byXid( xid );
        print( "AutoThrottle: " + source.name );
        
        // get data points
        
        var haveWetBulb = false;
        var points = reflectPointsList( source );
        for( j = 0; j < points.length; j++ ) {
            
            point = points[ j ];
            
            if( point.name == "Auto Throttle" ) {
                var at = point.runtime.value;
                print( "Auto Throttle " + at );
                }
            }
            
            if( point.name == "Water") {
                var water = point.runtime.value;
                var waterRuntime = point.runtime;
                print( "AutoThrottle: Water " + water );
            }
            
            if( point.name == "Wet Bulb") {
                var wetBulb = point.runtime.value;
                haveWetBulb = true;
                print( "AutoThrottle: Wet Bulb " + wetBulb );
            }
                    
            if( point.name == "Auto Limit") {
                var limit = point.runtime.value;
                print( "AutoThrottle: Auto Limit " + limit );
            }
        }
        
        // auto throttle logic
        if( ! haveWetBulb ) {
            print( "AutoThrottle: no wet bulb available" );
    
        }
        if( wetBulb < 16 )   {
            x = 4;
        }
        else if( wetBulb < 20)
        {
            x = 3;
        }
        else if( wetBulb < 24)
        {
            x = 2;
        }
        else if( wetBulb < 28 )
        {
            x = 1;
        }
        else
        {
            x = 0;
        }
    
        if( x > limit )
        {
            x = limit;
        }
        if( at ) {
            waterRuntime.set( x );
            print( "AutoThrottle: water set to " + x );
        }
    function ValveMapper2( xid )
    {
        // get the virtual source
        var source = DataSourceQuery.byXid( xid );
        print( "ValveMapper: " + source.name );
        
        // get the associated ADAM, if it exists
        
        var res = source.name.split( "VIRT");
        var adamName = res[ 0 ] + "ADAM";
        var adamSource = DataSourceQuery.query('eq(name,' + adamName +')');
    
            // handle no ADAM or more than one ADAM
        
        var adamCount = adamSource.length;
        if( adamCount == 0 ) {
            print( "no ADAM found for " + source.name );
            return;
        }
        if( adamCount > 1 ) {
            print( "multiple ADAMs found for " + source.name );
            return;
        }
    
        // get water setting from virtual
        
        print( "getting water setting from virtual");
        var vpoints = reflectPointsList( source );
        for( j = 0; j < vpoints.length; j++ ) {
            
            point = vpoints[ j ];
            
            if( point.name == "Water" ) {
                water = point.runtime.value;
                break;
            }
        }
    
        // get water data points from ADAM
        var apoints = reflectPointsList( adamSource[0] );
        var w1runtime, w2runtime, w3runtime, w4runtime = null;
        
        for( j = 0; j < apoints.size(); j++ ) {
            
            var point = apoints[ j ];
            if( point.name == "Water1" ) {
                w1runtime = point.runtime;
            }
            if( point.name == "Water2" ) {
                w2runtime = point.runtime;
            }
            if( point.name == "Water3" ) {
                w3runtime = point.runtime;
            }
            if( point.name == "Water/Fan" ) {
                wfruntime = point.runtime;
            }
        }
        
        //set water data points
        
        var w1 = false;
        var w2 = false;
        var w3 = false;
        var wf = false;
        
        if( water >= 1) wf = true;
        if( water >= 2) w1 = true;
        if( water >= 3) w2 = true;
        if( water >= 4) w3 = true; 
        
        print( wf, w1, w2, w3 );
        wfruntime.set( wf );
        w1runtime.set( w1 );
        w2runtime.set( w2 );
        w3runtime.set( w3 );
                
    }
    function WaterControl2( xid )
    {
        AutoThrottle2( xid );
        ValveMapper2( xid );
    }
    

    ...and then it quit working, issuing the following error message when validation is attempted:
    ReferenceError: "wetBulb" is not defined at line: 134

    wetBulb isn't even referenced in that function, let alone at line 134.

    I have had a similar problem before, and can't recall how I worked around it.

    Edit:

    Trying to validate other scripts, I find that they all fail validation with precisely the same error message! Same variable, same line - even for scripts with no more than 10 lines!

    Second edit:

    If I try to validate an empty script, the behavior is exactly the same.


  • Hi pyeager

    If I try to validate an empty script, the behavior is exactly the same.

    Do you have any global scripts defined?

    It may be a permissions issue. Do your scripts have superadmin / adequate permissions?


  • @phildunlap said in Bogus referenceError?:

    Do you have any global scripts defined?

    The script provided as an example is in fact a global script.

    It may be a permissions issue. Do your scripts have superadmin / adequate permissions?

    No change has been made to script permissions. The scripts were all running fine before this error occurred. Now none of them run. Every single script emits the same error on validation.


  • Perhaps this might help.

    I shut down all of my scripting data sources, waited a while, then enabled one of them.

    Here is what showed up in ma.log:

    INFO 2019-07-18T17:31:32,920 (com.serotonin.m2m2.rt.RuntimeManagerImpl.initializeDataSourceStartup:403) - Data source 'virtIterator' initialized
    ERROR 2019-07-18T17:31:35,001 (com.serotonin.m2m2.util.timeout.TimeoutTask.run:61) - Uncaught Task Exception
    java.lang.IllegalArgumentException: Context must be initialized first
    at io.jsonwebtoken.lang.Assert.isTrue(Assert.java:38) ~[jjwt-0.9.0.jar:0.9.0]
    at com.infiniteautomation.mango.util.script.CompiledMangoJavaScript.execute(CompiledMangoJavaScript.java:254) ~[mango-3.6.3.jar:?]
    at com.serotonin.m2m2.scripting.ScriptDataSourceRT.execute(ScriptDataSourceRT.java:204) ~[?:?]
    at com.serotonin.m2m2.scripting.ScriptDataSourceRT.doPoll(ScriptDataSourceRT.java:170) ~[?:?]
    at com.serotonin.m2m2.rt.dataSource.PollingDataSource.doPollNoSync(PollingDataSource.java:228) ~[mango-3.6.3.jar:?]
    at com.serotonin.m2m2.rt.dataSource.PollingDataSource.scheduleTimeoutImpl(PollingDataSource.java:183) ~[mango-3.6.3.jar:?]
    at com.serotonin.m2m2.rt.dataSource.PollingDataSource$1.scheduleTimeout(PollingDataSource.java:85) ~[mango-3.6.3.jar:?]
    at com.serotonin.m2m2.util.timeout.TimeoutTask.run(TimeoutTask.java:59) ~[mango-3.6.3.jar:?]
    at com.serotonin.timer.Task.runTask(Task.java:179) ~[mango-3.6.3.jar:?]
    at com.serotonin.timer.TaskWrapper.run(TaskWrapper.java:23) ~[mango-3.6.3.jar:?]
    at com.serotonin.timer.OrderedThreadPoolExecutor$OrderedTaskCollection.run(OrderedThreadPoolExecutor.java:336) ~[mango-3.6.3.jar:?]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[?:1.8.0_211]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[?:1.8.0_211]
    at java.lang.Thread.run(Thread.java:748) [?:1.8.0_211]


  • And here is an example of a scripting data source that suddenly quit working:

    var sources = DataSourceQuery.query('like(name,polecat*VIRT)&limit(10)');
    for(var i = 0; i<sources.length; i++ ) {
        
        var source = sources[ i ];
        WaterControl( source.xid );
        RelayLink( source.xid );
    
    }   
    

    Validation of this script generates the very same error message:

    ReferenceError: "wetBulb" is not defined at line: 134

    WaterControl and RelayLink are global scripts.

    WaterControl declares wetBulb at line 26, and references it at lines 38, 41, 45, and 49.

    RelayLink makes no reference whatsoever to wetBulb.

    Attempts to validate WaterControl and RelayLink result in the exact same error message shown above in this post.


  • @pyeager

    You have a syntax error in the 1st script you posted. It has the correct number of parenthesis but the ordering is such that some of the code is outside of a function block.

    Since every global script is executed anytime you execute or validate any Mango JavaScript this results in the code being executing and various variables not being defined in the block of code that it outside the function blocks of your global script.

    You have an errant } on line 17:

            if( point.name == "Auto Throttle" ) {
                var at = point.runtime.value;
                print( "Auto Throttle " + at );
                }
            }
    

  • Terry:

    Thanks for pointing out my syntax error.

    Is it unfair to expect that the script error message point to the actual error, and perhaps even the file in which the error exists?

    Also, where would I find scripts so that I can edit them with an editor I am more accustomed to?


  • Did the validation on the global script itself not do this? It wouldn't identify where the errant } was, but it would surely point out that it doesn't run properly and where it failed to do so.


  • The error message says nothing about what file the error occurred in, and when it indicates the location of an error, the indicated line bears no relationship to the reported error.

    One might assume the error exists in the script being validated, but we know that is not the case.


  • You are again talking about the validation of the point, yes? When the global script was modified, did not that validation show it?


  • The error message was exactly the same, no matter which script was being validated.

    The error message pointed to a line in some script, but never to a line referencing the variable noted in the error message.


  • No, the script editor on the global script would have shown you the line it encountered trouble at.

    The point is taken that a message on other scripts could suggest the global scripts are where the error is. But, it is good to test scripts when you modify them. Currently the validation on the backend will prevent saving syntax errors, but the error here is at runtime in referencing an undefined. We could modify the validation to execute the script, as the validate button on the global scripts page does.


  • @phildunlap said in Bogus referenceError?:

    No, the script editor on the global script would have shown you the line it encountered trouble at.

    Rather than continuing to insult my intelligence, would you please re-read my initial post?

    My initial post includes a complete global script, as was pointed out in a subsequent message.

    The error message most certainly did not point to the location of the error.


  • Okay, I think I know what happened. I was talking about these things,

    0_1563829023934_pyeager-forum-script.png

    But I was able to get it misaligned and reporting less than helpful line numbers by using more global scripts, Thanks for bringing that to our attention. I also saw that if I had saved the script with an error in it, then subsequent modifications of the script would still produce the same error until saved, which was caused by trying to add the saved version of the global script into the script engine, which doesn't seem quite right.

    Curious that I didn't see the same validation error as you.

    Edit: It appears the line numbers can only get off this way by saving a global script that produces this sort of error. If the global script does run without error, the line numbers for issues in the scripts in meta points and scripting sources should be correct when those then have syntax or reference errors.


  • Thank you for taking a second look.

    Clearly, your test did not duplicate my situation.

    Your test referenced a value that in fact did not exist, and produced an error message that pointed to the reference accurately.

    In my situation, as stated early on (four days ago, in fact), there was no reference to the variable called out in the error message anywhere near the line called out in the error message.

    Furthermore, as it turns out, the error message had absolutely nothing to do with the problem. It was improper placement of curly braces. There was in fact no reference to an undefined variable. All of this is documented here on this thread.


  • Thank you for taking a second look.

    Certainly.

    Clearly, your test did not duplicate my situation.

    I could have posted a screenshot of it putting the error marker on line 42 where it didn't belong, as I alluded to in saying I was able to achieve it by using multiple global scripts. Did you only have one global script? The only way I saw to achieve it there is also documented in my previous post, saving the one with the error and then trying to validate some revision of it.

    Your test referenced a value that in fact did not exist, and produced an error message that pointed to the reference accurately.

    In my situation, as stated early on (four days ago, in fact), there was no reference to the variable called out in the error message anywhere near the line called out in the error message.

    The global scripts are executed by the script engine before the meta point / scripting data source / event handler / etc and that is where the line number and message were coming from. Furthermore for efficiency all global scripts are bundled together before being handed to the script engine, so that's where the line number can be off even relative to the global scripts' line numbers.

    Furthermore, as it turns out, the error message had absolutely nothing to do with the problem. It was improper placement of curly braces. All of this is documented here on this thread.

    Yeah, the function block was closed to early and there were statements that referenced things which weren't defined. The script engine has no way of knowing where a curly brace in defining a function body went wrong...


  • Did you only have one global script? The only way I saw to achieve it there is also documented in my previous post, saving the one with the error and then trying to validate some revision of it.

    Yes, I have several global scripts.

    Perhaps it might help to warn users that having multiple global scripts might make finding errors more difficult. Or better yet, modify things so that the error message details what script and/or function the error occurs in.


  • Perhaps it might help to warn users that having multiple global scripts might make finding errors more difficult.

    I have created three git issues for this thread, two private one public. Issues being,

    1. Execute global scripts in save validation to ensure they execute (as opposed to compiling, which is what is done now, and would catch syntax errors)
    2. Do not add global scripts to one another during validation of global scripts
    3. Report exceptions from global functions better: https://github.com/infiniteautomation/ma-core-public/issues/1462

    Edit: they're only private because global scripts is in one of our private repositories


  • Thank you!