• I
    iperry

    Heya,

    I seem to be struggling with the syntax and layout of a model for use with Freemarker.

    The list of data points returned from DataPointQuery works as-is but if I try to create my own model, based on the data points list, I get the error: The value you try to list is an extended_hash (wrapper: f.t.SimpleHash), thus you must specify two loop variables after the "as"; one for the key, and another for the value, like <#... as k, v>).

    I want to create a model as I want to include information that isn't available in the records for each data point returned in the query.

    To me, this simple model appears similar to the data points but does not work:

    var tmpRecs = [
        {deviceName: 'PCU_110020', path: 'PCU_110090'},
        {deviceName: 'PCU_110021', path: 'PCU_110090'},
        {deviceName: 'PCU_110022', path: 'PCU_110090'}
    ];
    

    Most of the information I have found on the net is more Java related than specifically javascript.

    Does anyone have an example of a model in javascript they have built or some pointers as to what I am doing wrong? heh

    Any suggestions would be appreciated.

    Thanks
    Ian

    posted in User help read more
  • I
    iperry

    Heya,

    Is there a setting for the number of retries that will be taken before an email fails? It appears that only 1 attempt to send the email is made, unless the app is restarted.

    Hopefully its just something I have missed.

    Thanks
    Ian

    posted in User help read more
  • I
    iperry

    Hi @MattFox

    Good suggestion to attempt to manually import the changes to the data point. When I did that, I got the "errors":

    Data point 'DP_xyz': intervalLoggingPeriod --> Must be greater than zero
    Data point 'DP_xyz': purgePeriod --> Must be greater than zero
    Data point 'DP_xyz': intervalLoggingSampleWindowSize --> Must be greater than zero
    Import complete

    It's odd that the import tool seems to imply that the import was successful. /shrug When I examine the fields, those values are set to zero, yet the data point was originally saved. Hmmm

    The next test was I exported the point from the ui instead and imported. Same "errors".

    Next, I just tried to save the data point in the ui and this time got an error! Hmmm

    What I discovered is that the copied data point I was using for testing didn't actually save properly. It looked like it had. The issue was that the copy process didn't copy the custom template used in the original. When I re-copied the point, the template wasn't applied and caused an error when saving. After selecting the template, the save was "successful".

    Then my function worked just fine to update the name. A bit of an adventure figuring that one out heh.

    Thanks
    Ian

    posted in User help read more
  • I
    iperry

    Heya,

    I am trying to create a function that will update the name of a data point. I have successfully used a similar function to create a point but this one does not appear to work:

    function updateDataPointName(deviceName, pointName, newName) {
    
        var dataPoints = JSON.parse(JsonEmport.getConfiguration("dataPoints")).dataPoints;
        // LOG.info(JSON.stringify(dataPoints));
        
        function findByName(list, deviceName, pointName) {
            for (var k = 0; k < list.length; k+=1)
                if (list[k].deviceName === deviceName && list[k].name === pointName)
                    return list[k];
            return undefined;
        }
    
        var point = findByName(dataPoints, deviceName, pointName);
        if (typeof point === 'undefined') {
            LOG.info('Could not find point with name '+deviceName+' - '+pointName);
        }
        else {
            point.name = newName;
            LOG.info(JSON.stringify(point));
        
            JsonEmport.setImportDuringValidation(true);
            JsonEmport.doImport(JSON.stringify({"dataPoints": [point]}));
        }
    }
    

    The logs show that the point name is being changed but when I check the point in the data source, the name was not changed. I don't see any errors in the ma.log either.

    Any suggestions? Can you change the data point name this way?

    Thanks
    Ian

    posted in User help read more
  • I
    iperry

    Heya,

    (v3.6.5)

    I have been tracking an issue that causes the MQTT data source to disconnect from its broker.

    What I have been seeing in the ma.log is:

    WARN  2020-02-21T08:38:12,594 (com.serotonin.m2m2.rt.dataSource.PollingDataSource.incrementUnsuccessfulPolls:150) - Data Source Application Virtual aborted 3093 polls since it started. 
    WARN  2020-02-21T08:45:15,170 (com.serotonin.m2m2.rt.dataSource.PollingDataSource.incrementUnsuccessfulPolls:150) - Data Source Mango Internal aborted 1494 polls since it started. 
    WARN  2020-02-21T08:45:15,191 (com.serotonin.m2m2.rt.dataSource.PollingDataSource.incrementUnsuccessfulPolls:150) - Data Source Internal Stats aborted 22 polls since it started. 
    ERROR 2020-02-21T08:45:15,249 (com.infiniteautomation.m2m2.mqtt.client.MqttClientDataSourceRT$1.connectionLost:632) - MQTT Connection Lost 
    org.eclipse.paho.client.mqttv3.MqttException: Connection lost
    	at org.eclipse.paho.client.mqttv3.internal.CommsSender.handleRunException(CommsSender.java:153) ~[?:?]
    	at org.eclipse.paho.client.mqttv3.internal.CommsSender.run(CommsSender.java:138) ~[?:?]
    	at java.lang.Thread.run(Thread.java:748) [?:1.8.0_212]
    Caused by: java.net.SocketException: Broken pipe (Write failed)
    	at java.net.SocketOutputStream.socketWrite0(Native Method) ~[?:1.8.0_212]
    	at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111) ~[?:1.8.0_212]
    	at java.net.SocketOutputStream.write(SocketOutputStream.java:155) ~[?:1.8.0_212]
    	at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82) ~[?:1.8.0_212]
    	at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140) ~[?:1.8.0_212]
    	at org.eclipse.paho.client.mqttv3.internal.wire.MqttOutputStream.flush(MqttOutputStream.java:49) ~[?:?]
    	at org.eclipse.paho.client.mqttv3.internal.CommsSender.run(CommsSender.java:107) ~[?:?]
    	... 1 more
    

    These errors seemed to occur on a fairly regular timing of about 3.5 hours. It wasn't until yesterday when I got the Mango internal source working that I saw that it was very regular.

    0_1582321040015_faa15e7a-bb27-4f23-8955-17b6d454f99b-image.png

    The log entries occur when the free memory is "reset" back to 1.2gb. The one anomaly in the middle is when the backup/purge occurs, at which time there are log entries regarding the aborted polling the mqtt lost connection.

    I have 2 environment setup with a very similar load:
    VM's with 2GB memory allocated, 4GB swap
    JVM: ~80% memory usage, 0-15% CPU usage
    JAVAOPTS="$JAVAOPTS -Xms1600m -Xmx1600m"
    1850 data points

    The dev environment, running v3.5.6, has a very different free memory usage. Other than log entries occurring at the time of backup/purge, the mqtt connection has not been lost.

    0_1582321527649_4e00329e-88f2-4cb9-aa5d-0e672b5a27be-image.png

    (You can see the influence of the backup/purge also in this chart)

    I am concerned with the mqtt connection being lost as it is possible that data will be missed. This occurred once during a backup when the connection was lost for 10mins.

    Is this issue due to the limited resources (memory) on the VM? I am not convinced it is as the dev environment does not show a similar behaviour. Is this issue due to v3.6.5 (compared to v3.5.6)?

    Is this behaviour expected during a backup/purge? Can it be mitigated?

    Any ideas would be great.

    Thanks
    Ian

    PS: as another comparison, I have a similar app running on a physical box with 32gb memory, JVM size of 2.8GB and 2300 data points and have not seen this behaviour (mqtt connection lost) v3.5.6.

    posted in User help read more
  • I
    iperry

    Hi @dgm

    You are close:

                options="{
                    synchronizeGrid: false, 
                    valueAxes:[
                        {title: 'Connected', titleColor: '#ff4d4d', minimum: 0, maximum: 1, integersOnly: true, baseValue: 2},
                        {title: '&deg;C', titleColor: '#ff4d4d', minimum: -50, maximum: 50}
                    ]
                }"
    

    Each axis is an element in the valueAxes array.

    Ian

    posted in Dashboard Designer & Custom AngularJS Pages read more
  • I
    iperry

    Hi @terrypacker

    Thanks for pointing me towards the audit trial. I hadn't realized what elements were tracked here.

    However, the audit trail doesn't offer any comparison tools, version tagging, etc that source control app would, like Github. This was my intention for saving the global scripts to an external file.

    Thanks
    Ian

    posted in User help read more
  • I
    iperry

    Hi Matt, Craig

    The functions I have created in the global scripts are being used by meta points and scripting data sources. I was not intending for them to be used by the mangoUI.

    My hope was that I could move the global scripts and have them reside in a file(s) on the server outside the database. Currently, if I want to version control the global scripts, I need to export them using the configuration tool, save that file and then commit to source control. Comparing versions is a challenge as the scripts are each saved as a string in a JSON object. Any comparison tools shows the entire string has changed.

    Updating (or creating) an app would then just require that I copy the file over instead of importing using the configuration tool. One less step to manage.

    I'm hoping I'm making sense :)

    Thanks
    Ian

    posted in User help read more
  • I
    iperry

    Heya,

    This seems like a simple thing to do but I haven't found anything that is. Maybe it has been a long week. heh

    What I have is a virtual point set to increment by 1 in a virtual data source that will poll every 1 second. I have a meta point that will reset that virtual point to 0 and enable it based on conditions of another point.

    Is this the way to create a counter that is triggered? It seems sorta complex.

    Thanks
    Ian

    posted in User help read more
  • I
    iperry

    Heya,

    I am trying to create a chart with a dynamic (1+) number of series. For example, I may have up to 3 temperature values that I want to chart but if 1-2 of them do not exist, I don't want their series to appear on the chart. I don't want to create multiple charts for each variation as this would be headache to update in the future.

    1. I found another post regarding hiding a series but it only seemed to hide the chart line. The legend and axis values were still displayed.
    2. I thought maybe if I set the series values parameter to null it might be ignored. That didn't work.
    3. I tried making a component but discovered that having a dynamic template didn't seem possible. Maybe this is but I haven't figured it out yet.
    4. The closest I came to success was when I created a directive. However, the chart was not displayed but the legend and download button were.

    0_1581719704497_1c8a178f-cff2-4b32-a08e-af43c57721c2-image.png

    userModule.directive('scaRampChart', ['$compile', function ($compile) {
    
    	var ctrl = this;
    
    	var getChart = function(attrs) {
    		console.log('attrs = '+JSON.stringify(attrs));
    
    	return '<ma-serial-chart style="height: 300px; width: 100%"' +
                
    	'series-1-values="'+attrs.pcuRamp+'"' + 
    	'series-1-title="Transmitter Ramp"' +
    	'series-1-color="#256eff"' +
    	
    	'series-2-values="vPcuActive"' +
    	'series-2-title="Transmitter Connected"' +
    	'series-2-color="#256eff"' +
    	'series-2-axis="right"' +
    	'series-2-type="step"' +
    	'series-2-graph-options = "{\'dashLength\': 5, \'fillAlphas\': 0.1}"' +
    
    	'legend="true"' +
    	'balloon="true"' +
    	'export="true"' +
    	'default-type="line"' +
    	'default-graph-options="{title: \'Comparison\'}"' + 
    	'options="{' +
    	'	synchronizeGrid: false,' +
    	'	valueAxes:[' +
    	'		{minimum: \'0\', maximum: \'4500\'},' +
    	'		{title: \'Connected\', titleColor: \'#ff4d4d\', minimum: 0, maximum: 1, integersOnly: true, baseValue: 2},' +
    	'		{title: \'&deg;C\', titleColor: \'#ff4d4d\', minimum: -50, maximum: 50}' +
    	'	]' +
    	'}">' +
    	'</ma-serial-chart>';
    	}
    
        var linker = function($scope, $element, $attrs){
    		// console.log('in linker...');
    		$element.html(getChart($attrs)).show();
            $compile($element.contents())($scope);
        };
    
        return {
            restrict: "E",
            replace: true,
            link: linker,
            scope: {
    			content:'=',
    			pcuRamp: '<?'
            }
        };
    }]);
    

    Is there something else that I should consider? Is the directive something I should continue to work on?

    Can the series be specified using a JSON string instead of the component parameters?

    Thanks
    Ian

    posted in User help read more