• Recent
    • Tags
    • Popular
    • Register
    • Login
    1. Home
    2. MattFox
    3. Best

    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
    • Profile
    • Following 1
    • Followers 12
    • Topics 63
    • Posts 1,283
    • Best 93
    • Controversial 0
    • Groups 0

    Best posts made by MattFox

    • RE: Publisher don't listen

      @Jérôme-Girard if you're using a non root user you'll need to configure linux to allow non root users to use sub 1024 ports.
      namely
      sudo sysctl net.ipv4.ip_unprivileged_port_start=502
      and
      sudo nano /etc/sysctl.conf
      then set
      net.ipv4.ip_forward=1

      That should enable you to fire the publisher up on 502

      Fox

      posted in Mango General
      MattFoxM
      MattFox
    • RE: Excel Reports Sent at Wrong Time

      This will be a handy post for those who are running cloud hosted solutions as there isn't a mangoES settings section for custom installs.

      posted in User help
      MattFoxM
      MattFox
    • RE: Charts for past 12 hours

      Correct, look under API Docs -> Components -> maSerialChart
      They have a complete guideline of what attribute tags to use to apply values. You will want the series-x-values where the x is the chart number.
      The Chart update rate is affected by the maPointValues components which you can also read about. The realtime="true" attribute will allow datapoints to update into the chart at the rate they change or are updated.
      If you don't want to average, make sure you set the rollup type to NONE. Alternatively, use the rollup-interval to set the interval duration between datapoints in the chart, note that changing from the live updating rate may mean you;ll need to average.

      posted in Dashboard Designer & Custom AngularJS Pages
      MattFoxM
      MattFox
    • Cannot build with maven for custom module

      Hi Radix Team, trying to build a custom dashboard package and I keep getting this error - looks like it's not in your repo anymore - got any suggestions?

      [ERROR] Plugin org.codehaus.mojo:build-helper-maven-plugin:1.9.1 or one of its dependencies could not be resolved: Failed to read artifact descriptor for org.codehaus.mojo:build-helper-maven-plugin:jar:1.9.1: Could not transfer artifact org.codehaus.mojo:build-helper-maven-plugin:pom:1.9.1 from/to ias-releases (https://maven.mangoautomation.net/repository/ias-release/): Transfer failed for https://maven.mangoautomation.net/repository/ias-release/org/codehaus/mojo/build-helper-maven-plugin/1.9.1/build-helper-maven-plugin-1.9.1.pom: Network is unreachable (connect failed) -> [Help 1]
      
      

      Fox

      posted in Mango feedback
      MattFoxM
      MattFox
    • RE: Advice on moving components / controllers / services out of userModule

      Fixed, just mixed up the full path of the file with the userModule URL after closer inspection.

      posted in User help
      MattFoxM
      MattFox
    • RE: Removing last edited page from the default load

      @phillip-weeks
      are your referring to this post you made last year?
      https://forum.infiniteautomation.com/topic/3077/is-it-possible-to-roll-back-a-latest-ui-update-to-the-previous-version/5

      Looks like Jared mentions something about wiping your cache....

      0_1557969475663_cb114c78-dc94-48e4-8372-81248930ef06-image.png

      posted in Dashboard Designer & Custom AngularJS Pages
      MattFoxM
      MattFox
    • RE: Pop up window (face plate)

      OK!
      As a starting point to work from. I'll work with you so you learn how it all works as you go...
      (All code is placed in the /opt/mango/overrides/web... directories)
      /modules/mangoUI/web/dev/components/settingsModal.js

      define(['angular', 'require'], function(angular, require) {
      'use strict';
      
      /* Date: 1/9/18
      	   Author: Matt "Fox" Fox
      	   Desc: component written to launch a modal dialog with either a built in template or just spit out a list of points to save one by one.
      	*/
      	settingsModalController.$inject = ['$mdDialog','maJsonStore'];
      		function settingsModalController ($mdDialog,maJsonStore)
      		{
      			var ctrl = this;
      			ctrl.mdDialog = $mdDialog;
      			ctrl.parsedOptions=[];
      			
      			ctrl.values={};
      			
      			this.$onInit = function()
      			{
      				if(this.points && !angular.isArray(this.points))
      				{
      					console.log('Error: points field not an array of point objects');
      				}
      				if(this.pointOptions && !angular.isArray(this.pointOptions) )
      				{
      					console.log('Error: points options field not an array');
      				}
      				ctrl.clickOffClose = ctrl.clickOffClose===true?true:false;
      				
      				
      				
      				
      				
      			};
      			
      			this.$onChanges = function(e)
      			{
      				console.log(e);
      				checkPoints();
      			}
      			
      			function checkPoints()
      			{
      				ctrl.parsedOptions=[];
      				if(ctrl.points && angular.isArray(ctrl.points))
      				{
      					if(ctrl.pointOptions && angular.isArray(ctrl.pointOptions) )
      					{
      						var ptName,ptDesc;
      						for(var i=0; i<ctrl.points.length; i++)
      						{
      							ptName=ctrl.points[ i ].name;
      							ptDesc='';
      							if(ctrl.pointOptions[ i ] && ctrl.pointOptions[ i ].hasOwnProperty('name') )
      							{
      								ptName = ctrl.pointOptions[ i ].name;
      							}
      							if(ctrl.pointOptions[ i ] && ctrl.pointOptions[ i ].hasOwnProperty('desc') )
      							{
      								ptDesc = ctrl.pointOptions[ i ].desc;
      							}
      							ctrl.parsedOptions.push( {name:ptName,desc:ptDesc} );
      						}
      					}
      					else
      					{
      						for(var i=0; i<ctrl.points.length; i++)
      						{
      							ptName=ctrl.points[ i ].name;
      							ptDesc='';
      						
      							ctrl.parsedOptions.push( {name:ptName,desc:ptDesc} );
      						}
      					}
      				}
      				else if(ctrl.pointOptions && angular.isArray(ctrl.pointOptions) && !ctrl.points )
      				{	
      					var ptId, ptName, ptDesc;
      					for(var i=0; i<ctrl.pointOptions.length; i++)
      					{
      						if(ctrl.pointOptions[ i ] && !ctrl.pointOptions[ i ].hasOwnProperty('name') )
      						{
      							// ctrl.pointOptions=[];
      							ctrl.parsedOptions=[];
      							return;
      						}
      						ptId=i;
      						ptDesc='';
      						ptName=ctrl.pointOptions[ i ].name;
      						if(ctrl.pointOptions[ i ] && ctrl.pointOptions[ i ].hasOwnProperty('id') )
      						{
      							ptId = ctrl.pointOptions[ i ].id;
      						}
      						if(ctrl.pointOptions[ i ] && ctrl.pointOptions[ i ].hasOwnProperty('desc') )
      						{
      							ptDesc = ctrl.pointOptions[ i ].desc;
      						}						
      						ctrl.parsedOptions.push( {id:ptId,name:ptName,desc:ptDesc} );
      					}
      				}
      			}
      			
      			/* DIALOG CODE */
      			ctrl.showDialogue = function(ev) {
      			   // ctrl.updateModals();
      			   if( ctrl.altTemplateUrl!==undefined  )
      			   {
      				   try
      				   {
      					   
      					ctrl.mdDialog.show({
      					  templateUrl:ctrl.altTemplateUrl, 
      					  parent: angular.element(document.body),
      					  targetEvent: ev,
      					  clickOutsideToClose: ctrl.clickOffClose
      					}).then(
      						function()
      						{
      							console.log('function if closed/hidden manually'); 
      						},
      						function()
      						{
      							console.log('function to fire if closed from clicking outside/cancelled');
      						}
      					);
      				   }catch(e){console.warn(e);}
      			   }
      			   else
      			   {
      				   try{
      					   
      					ctrl.mdDialog.show({
      					  contentElement: '#settingsModal',
      					  parent: angular.element(document.body),
      					  targetEvent: ev,
      					  clickOutsideToClose: ctrl.clickOffClose
      					}).then(
      						function()
      						{
      							console.log('function if closed manually'); 
      						},
      						function()
      						{
      							console.log('function to fire if closed from clicking outside/cancelled');
      						}
      					);
      				   }catch(e){console.warn(e);}
      				}
      			};
      			
      			ctrl.hideDialogue = function() {
      				ctrl.mdDialog.hide();
      			};
      
      			ctrl.cancel = function() {	  
      				ctrl.mdDialog.cancel();
      			};
      			/* DIALOG CODE END*/
      			
      			/* JSON Store Stuff: */
      			ctrl.saveToStore = function(data=null)
      			{
      				
      				var item = maJsonStore.newItem( ctrl.jsonStore.toLowerCase() );
      				item.jsonData = data===null ? ctrl.values : data;
      				item.readPermission= "user";
      				item.editPermission= "user"; //can change this at your leisure or we can break it out into a setting...
      				
      				var r = item.$save();
      				
      				if(r.status)
      				{ 
      				}
      				else
      				{ 
      				}
      			};
      			
      			ctrl.loadFromStore = function()
      			{
      				maJsonStore.get({xid: ctrl.jsonStore.toLowerCase() }).$promise.then(function(item) {
      				ctrl.values = item.jsonData;
      			});
      			/* JSON Store Stuff END: */
      			};
      			
      			/* Virtual Point Save stuff */
      			ctrl.saveToPoint = function()
      			{
      				if(ctrl.savePoint===undefined)
      				{
      					alert('Point to save to not set as attribute!');
      					return;
      				}
      				ctrl.savePoint.setValue( JSON.stringify(ctrl.values) );
      			};	
      			
      			/* Virtual Point Save stuff END */
      	}
      		
      		
      		
      	
      	var settingsModal={
      		bindings:{
      			jsonStore: '<?', 		//Store name to save settings to
      			savePoint: '<?', 		//alternatively, save my JSON to a virtual pt, MUST BE TYPE DATAPOINT...
      			altTemplateUrl:'=?', 	//If we want to use the popup to show something else: use this template...
      			modalTitle:'=?', 		//seemed like a good idea at the time... will only work if altTemplateUrl is empty
      			clickOffClose:'=?', 	//set to true to click outside modal to shut it
      			pointOptions:'<?', 	//Alternate names for points,  (object array) [{id:'',name:'',desc:''}], id used for key name if using json/virtual point save
      			points: '<?',			 //Array of points to set individually
      		},
      		controller: settingsModalController,
      		templateUrl:'/modules/mangoUI/web/dev/views/modalDemo.html'
      	};
      	
      	return settingsModal;
      });
      

      and the template markup to add:
      /modules/mangoUI/web/dev/views/modalDemo.html

       <ma-button  hue="hue-2" palette="primary" label="Open Dialogue" ng-click="$ctrl.showDialogue()" raised="true"></ma-button>
       <div ng-if="!$ctrl.altTemplateUrl" style="visibility: hidden">
          <div class="md-dialog-container" id="settingsModal">
            <md-dialog layout-padding>
      			<md-dialog-actions><md-button ng-if="!$ctrl.clickOffClose" ng-click="$ctrl.cancel()" class="md-primary">x</md-button></md-dialog-actions>
       <div ng-if="!$ctrl.points && !$ctrl.parsedOptions">
      		Custom markup needed!
      		</div>
      		 
             <h1 ng-if="$ctrl.modalTitle!==undefined">{{$ctrl.modalTitle}}</h1> <small ng-if="$ctrl.clickOffClose">Click outside dialogue to close</small>
      		
      		<div ng-if="$ctrl.points">
      		<md-input-container ng-repeat="(index,point) in $ctrl.points" style="display:block;width:100%;">
      	   {{$ctrl.parsedOptions[index].name}}
      			<br/>	
      	   {{$ctrl.parsedOptions[index].desc}}
      			<br/>	
      			
      		<span style="display:inline-block;">Current Value: <ma-point-value style="display:inline-block;" point="point" ></ma-point-value></span>
      		 <ma-set-point-value  point="point" show-button="true"></ma-set-point-value> 
      		</md-input-container>
      		</div>
      		<div ng-if="!$ctrl.points && $ctrl.parsedOptions.length>0">
      			<md-input-container ng-repeat="input in $ctrl.parsedOptions">
      			{{input.name}}<br/>{{input.desc}}
      			<input ng-model="$ctrl.values[ input.id ]"/>
      			</md-input-container>
      		</div>
      		
            </md-dialog>
          </div>
        </div>
      

      More than happy to help you work through this (it will be a bit of a crash course)
      I've not added the buttons on the template for saving using a virtual point or JSON store, but that can be added quite easily.
      Basically you can generate a popup which will populate with inputs that can be named, given an ID and a description if necessary. This can also be used to override point names to more 'user friendly' equivalents for your users if they're filling out items in the dialogue box.

      inside the userModule.js directory (assuming that's the name of the file you've followed from Jared's tutorial) you'll want this structure:

      /userModule.js
      /components/settingsModal.js
      /views/modalDemo.html

      and inside userModule.js you'll want this:

      define(['angular', 'require','./components/settingsModal.js'], function(angular, require,settingsModal) {
          'use strict';
       var userModule = angular.module('userModule', ['maUiApp']);
      try {	
      	userModule.component('settingsModal', settingsModal);
      }
      catch(e){console.log(e);}	
          return userModule;
      });
      

      Markup in the dashboard page builder will be:

      <settings-modal point-options="[{id:'test',name:'input 1',desc:'input test 1'},{id:'test2',name:'input 2',desc:'input test 2'}]" points="vp" click-off-close="true"></settings-modal>
      

      See if you can get the popup showing for you first. I'm using 3.4.1 so I'm not completely sure if this will be affected in your version of mangoUI...

      Fox

      EDIT: sorry I'll be sure to add some more code comments later...
      New Edit: added data to save to store as an optional argument

      posted in Wishlist
      MattFoxM
      MattFox
    • RE: MQTT Publish

      @Rav-Panchalingam from what I've seen. Mango can only subscribe. Not publish. They've never implemented a publisher despite requests dating back 3+ years

      posted in User help
      MattFoxM
      MattFox
    • RE: How to change date format on chart?
      /ui/docs/ng-mango/ma-serial-chart
      

      Read the docs under API Docs -> components -> maSerialChart

      there's an attribute you can set to alter the format:

      time-format
      (optional)
      string	
      The moment.js time format to be used in displaying timestamps on the X axis.
      

      Put your moment.js format in there and that will let you set the format to 'DD mm' etc

      posted in Mango Automation general Discussion
      MattFoxM
      MattFox
    • RE: Big News! Infinite Automation, Mango and BitBox USA have merged to create Radix IoT

      Congrats for making it through the other side. Would be good to have a chat considering currently our system doesn't scale well with mango. If the merger can help with this that'd be grand. It's the bottleneck in our system and I'm struggling to streamline what we have.

      Fox

      posted in Announcements
      MattFoxM
      MattFox
    • RE: Once again MQTT over HTTP

      Not a great deal to share really! I used nodeJS and the aws publishing library to send to a third party. Once set up, you just run the nodeJS with the express library or another restful style service then use the body of the request to be published out of subscribed mqqt topic.

      Sorry if it's a bit vague! If you want a how to I'll write a tutorial next week when I'm back at my work computer. Hope it doesn't step on Joel's toes..

      Fox

      posted in Wishlist
      MattFoxM
      MattFox
    • RE: Performing a "set" on a Persistent TCP point

      @psysak If youn mean you have a mango unit publishing data and you want to be able to set back the other way, The only way to do so is to create a publisher going back the other way. That way when you set the datapoint on the mango unit receiving the published data the changes are pushed back to the initial mango unit doing the publishing. This does mean you would have a new datasource to capture and hold the set data.

      posted in User help
      MattFoxM
      MattFox
    • RE: Over the last few month very little participation from staff.

      Sorry I cannot answer all the posts. I am not a V4 user. But I do understand your frustrations. I'll have to leave one of the staff to respond to you here.

      Fox

      posted in Mango Automation general Discussion
      MattFoxM
      MattFox
    • RE: Announcing the New Mango 5 Pre-Release: Download Now and Explore Exciting Features!

      @tungthanh500
      https://forum.mango-os.com/category/5/mango-feedback

      If you can tag your post with mango5, it will make it easier to filter

      Fox

      posted in Announcements
      MattFoxM
      MattFox
    • RE: How I use chart from AmCharts

      Seeing how amcharts have kindly given the source code on how to do this; you would need to get your required data points. Use a get point values query for the respective data points required. Use a "1 YEARS" AVERAGE/SUM rollup if you have multiple values for a given year depending on what you are calculating.

      Next write an angular component/directive which creates a time-line pie instance, and format the incoming point values with their points into the
      "[ 'year' : [ { 'value' : 'datapointValue1', 'label': 'point 1 name'}, { 'value' : 'datapointValue2, 'label': 'point 2 name'} ]" format.

      The supplied source code on amcharts will enable you to create animate effects etc.
      To get yourself started, I suggest you look at Jared's pie chart directive then build on top of that in a new file, just be sure to change the name from pieChart to timePieChart so you don't cause any problems with the native UI components.

      Hope that helps!

      Fox

      posted in Dashboard Designer & Custom AngularJS Pages
      MattFoxM
      MattFox
    • RE: Text on gauges

      I can tell you that the ma-gauge-chart tag is an angularJS component so it will not show anything between the tags, and thus not be rendered.
      Units usually show if you have set the unit field on the individual datapoint under /data_sources.shtm.
      Feel free to take screenshots and describe further what you are trying to accomplish.

      Fox

      posted in User help
      MattFoxM
      MattFox
    • RE: Excel Report location

      @tungthanh500 Going out on a limb here (and assuming you've got mango4), but I suspect it's
      mango/data/excelReports/report-data

      Fox

      posted in Mango Automation general Discussion
      MattFoxM
      MattFox
    • RE: Resources Mango needs

      6 Core xeon 15GB server
      Given Mango 10G to run with, htop seems to show it asking for 14 in a virtual sense, not sure if that means I need to crank it up or not..
      377 Datasources, A little over 8200 points, About half of those being updated by API from a third party system. All points are updating ranging from 20 seconds to 15 minutes. I'd argue about 500 points are meta points.
      193 users, I've always got about 2/3 thirds having active sessions on the system.
      CPU hits approx 20% every once in a while. I've got 700 max threads running in settings to ensure mango can just smack everything out as it needs. But after having issues last week with tags being saved to show status information I was beginning to wonder if there's more I'm missing....

      posted in Mango feedback
      MattFoxM
      MattFox
    • RE: Chart Axes min/max not working

      correct, you need to user the strictMinMax:true property to force the axes to be a given range

      posted in Dashboard Designer & Custom AngularJS Pages
      MattFoxM
      MattFox
    • RE: Create event detector that applies to all/specific datapoints

      @phildunlap said in Create event detector that applies to all/specific datapoints:

      You'd have a bunch of options to hack it up.

      You had me at hack
      I've got a status dashboard doing something similar already. Although I can likely extend what you've done here and implement an email with a template listing all iffy datapoints. It's not an alarm per se but it sure is a darn good start.
      I'll put it in the wishlist. I think it'd be good to datasource/point template wide alarm settings that individual points have.
      Inidividual point alarms override template -> template override datasource. That's my idea.

      Thanks again Phil!

      Fox

      posted in User help
      MattFoxM
      MattFox