• Recent
    • Tags
    • Popular
    • Register
    • Login
    1. Home
    2. iperry
    3. Posts

    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 Mango 5 Documentation Website
    I
    • Profile
    • Following 0
    • Followers 0
    • Topics 39
    • Posts 95
    • Best 2
    • Controversial 0
    • Groups 0

    Posts made by iperry

    • Data point query limited to 100 points returned

      Heya,

      v3.7.7

      For some time, I was encountering an odd behavior in displaying the value of data points for a device. Some devices would be fine and some would have missing data points. I confirmed that the data points I expected were in the data source and had a valid value but for some reason were not being returned in the point query.

      Finally I had some time to devote to investigate this issue and discovered that there is an implicit limit of 100 on a data point query.

      For example, the number of data points returned by the follow queries should be the same:

      <ma-point-query query="{deviceName: $ctrl.deviceName}" sort="'name'" points="ptstmp"></ma-point-query>
      *{{ptstmp.length}}*
      <ma-point-query query="{deviceName: $ctrl.deviceName}" sort="'name'" limit="300" points="ptsDevice"></ma-point-query>
      *{{ptsDevice.length}}*
      
      

      However, the lengths of the arrays where 100 and 153 respectively.

      According to the API docs in the application:
      "All data points added to your Mango system will display by default, unless you set the limit property."
      and
      "Limit takes place after query and sorting (no limit by defualt)"

      The docs would indicate that if no limit is specified, then all of the data points matching the query should be returned.

      I am not sure if there is a possible issue with the docs or the behavior of the point query function.

      The issue can be fixed by adding limit="-1" to the query but it is a maintenance challenge to update all uses of the point query in the app.

      Thanks
      Ian

      posted in User help
      I
      iperry
    • How to disable fonts from being loaded

      Heya,

      What is the best method for disabling or removing fonts that are unneeded, such as greek, latin, vietnamese, etc? Loading these fonts can take some time over a cellular modem and makes the initial connection to the application appear slow.

      I found 2 packages, OpenSans and Roboto, under /web/resources/fonts but I am unsure the best way to disable them. I am a little hesitant to remove them all together as I don't know their impact on the rest of the application.

      Any suggestions?

      Thanks
      Ian

      posted in User help
      I
      iperry
    • Creating model for use in Freemarker

      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
      I
      iperry
    • Email retries setting

      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
      I
      iperry
    • RE: Changing the name of a data point using a script

      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
      I
      iperry
    • Changing the name of a data point using a script

      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
      I
      iperry
    • Consumption of JVM memory leads to disconnect of MQTT data source

      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
      I
      iperry
    • RE: Adding multiple axes

      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
      I
      iperry
    • RE: Moving global script functions to a server file

      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
      I
      iperry
    • RE: Moving global script functions to a server file

      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
      I
      iperry
    • Triggering a counter data point to enable and restart

      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
      I
      iperry
    • Creating a chart with dynamic number of series

      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
      I
      iperry
    • Moving global script functions to a server file

      Heya,

      I would like to move the global scripts I have created to an external file(s) on the server to help with deployment and source control. Is this possible? Where/how would the file reside on the server? How would the file be included when the app was loaded and how would I call the functions in the file?

      Thanks
      Ian

      PS: mango v3.5.6

      posted in User help
      I
      iperry
    • Adding condition checks to ma-set-point-value

      Heya,

      This question is in 2 parts:

      Is there a way to display a response to the user that the value they entered has exceeded the bounds specified in the data point?

      I created a virtual point "Angle X Setpoint" and set the high and low limit to be 5 and 0 (and checked Prevent extreme sets). When a user enters a value into the field and clicks set, the operation appears to succeed as the button shows the check mark and there is no error. However, when you examine the data point, the value was not saved.

      Does ma-set-point-value have the ability to display an error response or at least show the save was unsuccessful?

      Do you have any suggestions if I wanted to add custom condition checks to the ma-set-point-value object? Would I have to create my own component so I could add the condition checks?

      Thanks
      Ian

      PS: mango v3.5.6

      posted in User help
      I
      iperry
    • RE: Migrating a custom page to a component

      Hi Matt,

      Thanks for the suggestion. Yes, I had to inject $stateParams (and maUser) into the controller to have access to that data,

          scaGroupViewController.$inject = ['$stateParams', 'maUser'];
      
      	function scaGroupViewController($stateParams, User) {
      		var ctrl = this;
      
      		this.stateParams = $stateParams;
      		this.User = User;
      
      

      Then I had to update my page to use the value from the controller. Retrieving parameters using ma-ui-state-params was no longer necessary.

      <!-- <ma-ui-state-params stateParams = $pageParams></ma-ui-state-params> -->
      
      <ma-point-query query="{$and: true, deviceName: $ctrl.stateParams.groupName, name: 'Group'}" sort="'name'" points="psGroup"></ma-point-query>
      
      <div ng-init="super = $ctrl.User.current.hasPermission('superadmin')"></div>
      

      I picked through some of the Mango component code in Github and found a few that used this pattern which helped. Which services and such I can/need to inject is still a challenge for me to figure out but your suggestion and the code helped.

      Thanks!
      Ian

      posted in User help
      I
      iperry
    • Migrating a custom page to a component

      Heya,

      I am trying to migrate the custom pages I have created in the application to components to facilitate source control and versioning but I am having an issue with passing url parameters. I believe I have created and registered the component as per the examples but I am not receiving the parameter as expected.

      Custom page:

      menu entry:

              {
                  "name": "ui.groupSummary",
                  "url": "/group-summary?groupName",
                  "linkToPage": true,
                  "permission": "user",
                  "menuText": "Group Summary",
                  "pageXid": "c137266c-ee8c-4d37-b93c-3f7de63d8d38",
                  "menuIcon": "insert_chart",
                  "menuHidden": true,
                  "weight": 1006
              },
      
      

      page call (from button):

      <md-button ui-state="'ui.groupSummary'" ui-state-params="{groupName: 'Group_01'}">Group 01</md-button>
      
      

      page markup:

      <ma-ui-state-params stateParams = $pageParams></ma-ui-state-params>
      stateParams.groupName = {{stateParams.groupName}}
      
      

      page display:
      0_1578509838625_f8265231-db3a-4b87-88f5-0ed4e50cf6d1-image.png

      Component page:

      menu entry (taken from userModule.js):

      	maUiMenuProvider.registerMenuItems([
      		{
      			name: 'ui.groupView',
      			url: '/group-view?groupName',
      			// linkToPage: true,
      			// permission: "user",
      			template: '<sca-group-view></sca-group-view>',
      			menuIcon: 'fa-home',
      			menuText: 'Group View',
      			menuHidden: true,
      			weight: 997,
      			params: {
      				noPadding: false,
      				hideFooter: false,
      			},
      		},
      	]);
      

      page call (from button):

      <md-button ui-state="'ui.groupView'" ui-state-params="{groupName: 'Group_01'}">Test</md-button>
      
      

      page display (same markup as custom page):
      0_1578510346784_fc0e529d-b1fa-4de8-95ee-723fbe17633f-image.png

      How do I pass url parameters to a page component?

      I didn't find any examples that had parameter passing so I figured the menu configuration would be the same between the JSON entry and the menu registration.

      Likely there is something simple I am missing. :)

      Aside: I would have thought the JSON entry and menu registration syntax would have been the same. However, using the linkToPage and permission parameters in the registration string throws errors.

      Thanks
      Ian

      posted in User help
      I
      iperry
    • Interfacing Mango with Digi RM

      Heya,

      Wondering if anyone has had any experience interfacing Mango with Digi RM (https://remotemanager.digi.com/)? I am trying to use either a HTTP Json receiver or retriever but haven't had much luck yet. Just wondering if it possible (good or bad experience) before I recreate a middleware app I used for another similar project.

      Thanks
      Ian

      posted in User help
      I
      iperry
    • RE: How to create data points to handle MQTT from multiple devices?

      For another option, the strategy I took was that I created global scripts to create the data points (MQTT/Modbus, virtual, meta) for my devices.

      The scripts I have are:
      dataPointJsonTempates
      --> This script contains the minimal set of values I need to set for each type of data point.
      createDataPointFunction
      --> This script contains the list of points I need for each of the devices. It loops through each list of points and calls the appropriate function below.
      createDeviceFunctions
      --> This script creates each of the appropriate data point, event detector, and event handlers.

      The intention was to detect the error generated when an unknown MQTT topic is subscribed to and create the required data points from the device id in the topic. I haven't gotten that working yet but it is a lower priority item at the moment.

      For now, I have a scripting data source to call the function:
      createDevice('PCU_110006');

      I have created multiple 'createDataPointFunctions' scripts for the different devices I need. The same pattern is applied.

      Ian

      posted in Mango Automation general Discussion
      I
      iperry
    • RE: Displaying the latest history timestamp for a data point

      Hi Phil,

      Good to know I wasn't missing something simple.

      I have created a simple component that stores and displays the timestamp only when the value changes:

      <ma-point-values point="pPCUAccelCnt" values="point1Values" latest="1" realtime="true"></ma-point-values>
      <sca-latest-timestamp value="{{point1Values[0].value}}" timestamp="{{point1Values[0].timestamp}}"></sca-latest-timestamp>
      

      Once I get some new test devices (and updated data), I will see if this works. :)

      Thanks
      Ian

      posted in User help
      I
      iperry
    • Displaying the latest history timestamp for a data point

      Heya,

      I am stumped with what seems a simple thing: displaying the latest history timestamp for a data point.

      A have a MQTT data point whose topic is being updated every 30 secs (ish). However, the value of the data point may only change once a day for example. I have set the data logging of the point to be "When point value changes".

      0_1566246510436_fb5df63f-38d6-45d3-86ac-78afeafb82e7-image.png
      Note: I originally had the data logging set to "timestamp changes", as showed in the history.

      When I display the timestamp, I get the current value "Aug 14 16:38" which is updated every 30 secs. I get the same behaviour when I display the values returned from ma-point-values. When I added realtime="false", the correct timestamp is displayed but is never updated unless the screen is refreshed.

      0_1566246877416_6a570a4b-1132-48e8-8b88-16b05db1b866-image.png

      <ma-calc input="psPCU | filter: {name: 'PCU Accel Event Count'} | maFirst" output="pPCUAccelCnt"></ma-calc>
      <ma-get-point-value point="pPCUAccelCnt"></ma-get-point-value>
      
      *{{pPCUAccelCnt.lastValue()}}*
      <span>Acceleration Count: <strong><sca-display-na value="{{pPCUAccelCnt.value}}"></sca-display-na></strong></span>
      <span>Latest Acceleration: <strong><sca-display-na value="{{pPCUAccelCnt.time | maMoment:'format':'MMM D, YYYY h:mm:ss A'}}"></sca-display-na></strong></span>
      Count ma-point-value: <ma-point-value point="pPCUAccelCnt" display-type="dateTime" date-time-format="LTS"></ma-point-value>
      Count ma-point-values: <ma-point-values point="pPCUAccelCnt" values="point1Values" latest="1" realtime="false"></ma-point-values>
      {{point1Values[0].timestamp | maMoment:'format':'MMM D, YYYY h:mm:ss A'}}
      

      As in my example above, I have tried a variety of ways to display the latest history timestamp but without success. I don't want to use the realtime flag either. For a shot, I tried getting the lastValue but I knew it wouldn't work.

      I could route the data point through a meta point to capture the timestamp but this is extra complexity for which seems something simple.

      Is there something simple I am missing? heh

      I encountered this before when displaying the timestamp of a virtual point. I discovered the polling update interval changed the timestamp. Turning the polling off fixed that issue.

      Thanks
      Ian

      posted in User help
      I
      iperry