Radix IoT Website Mango 3 Documentation Website Mango 4 Documentation Website Mango 5 Documentation Website

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.

  • what is for mah2.trace.db

    2
    0 Votes
    2 Posts
    1k Views
    phildunlapP
    Hi Antonio, It's a log file. Open it in a text editor.
  • Mango JVM ram value

    2
    0 Votes
    2 Posts
    1k Views
    phildunlapP
    Hi Antonio, https://help.infiniteautomation.com/using-startup-extensions/
  • Delete email settings

    4
    0 Votes
    4 Posts
    2k Views
    phildunlapP
    <category name="com.serotonin.m2m2.rt.maint.work.EmailWorkItem"><level value="error"/></category>
  • HTTP Retriever and JSON data

    json httpretriever
    4
    0 Votes
    4 Posts
    3k Views
    CraigWebC
    No problem. to convert it to decimal you could use alphanumeric meta point and in your script do the following. [image: e7mJD5n.png]
  • Enabling SSL Mango will not start

    5
    0 Votes
    5 Posts
    2k Views
    phildunlapP
    Hi OldSmokey, To add another possibility, ensure the user running Mango has permissions to read the keystore file at the operating system level. Logs would make it less of a guessing game, though.
  • Mangos network architecture for a big plant

    10
    0 Votes
    10 Posts
    3k Views
    phildunlapP
    For Mango 2 the point restrictions and the unique login were the core restrictions, and then one needed to buy licenses for modules with varying levels of restriction in the modules. The free core was not intended for commercial use, but the Mango/LICENSE file didn't address that, and the user didn't have to agree to a EULA that stated such upon using the software. For Mango 3 free and unlicensed cores are restricted to personal, educational, or evaluation purposes. Module licenses (for Infinite Automation modules) are only on a few modules now, like Excel Reports or Cloud Connect. All non-free core licenses enable legitimate commercial use, and only functional restrictions like point count would apply depending on the type of license purchased. Your purchase options for a particular instance can be assess by clicking the 'Register GUID' or 'Update license' button to open a store.infiniteautomation.com page for that instance on either the /modules.shtm or the /ui/administration/modules pages, If you have some specific questions about the licensing I can try to answer those for you.
  • Dinamic scaling factor

    2
    0 Votes
    2 Posts
    2k Views
    CraigWebC
    Hi Etantonio Since the scale factor is dynamic. you will need to make a meta point, using the points. add the 2 value to your meta points and then do something like this in your script. return powerValue * Math.pow(10, scalingFactor)
  • Is cc-link protocol supported in Mango?

    4
    0 Votes
    4 Posts
    2k Views
    CraigWebC
    Not to worry it is plain old Modbus. I have done quite a few systems with the Mitsu inverters. Make sure you take adequate noise prevention measures on your RS-485 bus.
  • wireless sensor temperature

    niagara
    1
    0 Votes
    1 Posts
    1k Views
    No one has replied
  • Personal web site is visible but mango management is not visible

    18
    0 Votes
    18 Posts
    7k Views
    phildunlapP
    Still weird to me that wouldn't produce errors if you launched at the command line! Thanks for sharing the resolution.
  • How to upgrade from mango 2.8.4 to mango 3.x.x ?

    5
    0 Votes
    5 Posts
    2k Views
    E
    you are right, now I am in version 2.8.8, thanks
  • Multiplicand and Augend on HTTP Receiver

    6
    0 Votes
    6 Posts
    3k Views
    phildunlapP
    Wont using virtual serial port limit this connection to 1 stream, ie 1 PI ? Yes, good suspicion! Yes I have control over the HTTP messages, so I can add anything to that, Great! So I would set up an HTTP receiver with only one point, Let's say its parameter name is 'data' (or maybe just d, for short). Then I'll publish to the receiver messages like POST / HTTP/1.1 User-Agent: Mango M2M2 HTTP Sender publisher Content-Length: 31 Content-Type: application/x-www-form-urlencoded Host: 127.0.0.1 Connection: Keep-Alive Expect: 100-continue Accept-Encoding: gzip,deflate data=s1z56.78+s2z78.90+s3z12.34 And put the http receiver point with Parameter name "data" into the context of a script like, var sensorTransforms = this.sensorTransforms; if(typeof this.sensorTransforms === 'undefined') { this.sensorTransforms = sensorTransforms = { //Use this map of sensor identifiers to transformation functions to // manipulate the value of the data s1: function(val) { return val*2 + 3; }, s2: function(val) { return val*6 - 12; }, s3: function(val) { return Math.pow(val, 2); } }; } function createPoint(identifier) { var newDp = JSON.parse(JsonEmport.dataPointQuery( 'eq(xid,DP_BaseQueueProcessorNumeric)')).dataPoints[0]; newDp.enabled = true; newDp.pointLocator.varName = identifier; newDp.name = "Sensor " + identifier; delete newDp.xid; //To generate a new XID, //or encode your own XID for reference elsewhere JsonEmport.doImport( JSON.stringify({"dataPoints": [newDp]}) ); } //Because there is a slight asynchrony, we need to track where we got to in the data // queue, so we'll use a context point for that. var unprocessedMessages = data.pointValuesSince(tracker.time); var lastTs = 0; for(var k = 0; k < unprocessedMessages.length; k+=1) { var sensorData = unprocessedMessages[k].stringValue.split(" "); for(var j = 0; j < sensorData.length; j+=1) { var pointData = sensorData[j].split("z"); if(typeof this[pointData[0]] === 'undefined' ) { createPoint(pointData[0]); } if( pointData[0] in sensorTransforms ) this[pointData[0]].set( sensorTransforms[pointData[0]](Number(pointData[1])) ); else this[pointData[0]].set( Number(pointData[1]) ); } lastTs = unprocessedMessages[k].time; } //Update the timestamp we have processed unto if(lastTs !== 0) tracker.set(!tracker.value, lastTs); And here's the JSON for the script and the base points (you will probably need to define a cron for the scripting data source, as the feature to have a scripting data source only be driven by context point updates has been added to 3.5 (which should see some sort of alpha release today or very soon). You would probably also need to create a "Numeric_All-Data" data point template. It also has the JSON for the HTTP receiver I tested with { "dataSources":[ { "xid":"DS_306b3fdc-b914-4187-9a4c-0024be71d52e", "name":"DataQueueProcessor", "enabled":false, "type":"SCRIPTING", "alarmLevels":{ "SCRIPT_ERROR":"URGENT", "DATA_TYPE_ERROR":"URGENT", "POLL_ABORTED":"URGENT", "LOG_ERROR":"URGENT" }, "purgeType":"YEARS", "updateEvent":"CONTEXT_UPDATE", "context":[ { "varName":"data", "dataPointXid":"DP_97ba3ae9-f9ca-4b36-a557-b07fc89824f1", "updateContext":true } ], "logLevel":"NONE", "cronPattern":"", "executionDelaySeconds":0, "historicalSetting":false, "script":"var sensorTransforms = this.sensorTransforms;\nif(typeof this.sensorTransforms === 'undefined') {\n this.sensorTransforms = sensorTransforms = {\n \/\/Use this map of sensor identifiers to transformation functions to\n \/\/ manipulate the value of the data\n s1: function(val) { return val*2 + 3; },\n s2: function(val) { return val*6 - 12; },\n s3: function(val) { return Math.pow(val, 2); }\n };\n}\n\nfunction createPoint(identifier) {\n var newDp = JSON.parse(JsonEmport.dataPointQuery(\n 'eq(xid,DP_BaseQueueProcessorNumeric)')).dataPoints[0];\n newDp.enabled = true;\n newDp.pointLocator.varName = identifier;\n newDp.name = \"Sensor \" + identifier;\n delete newDp.xid; \/\/To generate a new XID,\n \/\/or encode your own XID for reference elsewhere\n JsonEmport.doImport( JSON.stringify({\"dataPoints\": [newDp]}) );\n}\n\n\/\/Because there is a slight asynchrony, we need to track where we got to in the data\n\/\/ queue, so we'll use a context point for that.\nvar unprocessedMessages = data.pointValuesSince(tracker.time);\nvar lastTs = 0;\nfor(var k = 0; k < unprocessedMessages.length; k+=1) {\n var sensorData = unprocessedMessages[k].stringValue.split(\" \");\n for(var j = 0; j < sensorData.length; j+=1) {\n var pointData = sensorData[j].split(\"z\");\n if(typeof this[pointData[0]] === 'undefined' ) {\n createPoint(pointData[0]);\n }\n if( pointData[0] in sensorTransforms )\n this[pointData[0]].set( sensorTransforms[pointData[0]](Number(pointData[1])) );\n else\n this[pointData[0]].set( Number(pointData[1]) );\n }\n lastTs = unprocessedMessages[k].time;\n}\n\n\/\/Update the timestamp we have processed unto\nif(lastTs !== 0)\n tracker.set(!tracker.value, lastTs);\n", "scriptPermissions":{ "customPermissions":"", "dataPointReadPermissions":"superadmin,superadmin", "dataPointSetPermissions":"superadmin,superadmin", "dataSourcePermissions":"superadmin,superadmin" }, "editPermission":"", "purgeOverride":false, "purgePeriod":1 }, { "xid":"DS_bcd20bf3-a723-4631-a5ce-77f409e54a46", "name":"DataQueueReceiver", "enabled":true, "type":"HTTP_RECEIVER", "alarmLevels":{ "SET_POINT_FAILURE":"URGENT" }, "purgeType":"YEARS", "setType":"PUBLISHER", "dateFormat":"DATE_FORMAT_BASIC", "deviceIdWhiteList":[ "*" ], "ipWhiteList":[ "*.*.*.*" ], "setPointUrl":"", "editPermission":"", "purgeOverride":false, "purgePeriod":1 } ], "dataPoints":[ { "xid":"DP_97ba3ae9-f9ca-4b36-a557-b07fc89824f1", "name":"Data Message", "enabled":true, "loggingType":"ALL", "intervalLoggingPeriodType":"MINUTES", "intervalLoggingType":"INSTANT", "purgeType":"YEARS", "pointLocator":{ "dataType":"ALPHANUMERIC", "binary0Value":"", "includeTimestamp":true, "parameterName":"data", "setPointName":"", "settable":false }, "eventDetectors":[ ], "plotType":"STEP", "rollup":"NONE", "unit":"", "simplifyType":"NONE", "chartColour":"", "chartRenderer":{ "type":"TABLE", "limit":10 }, "dataSourceXid":"DS_bcd20bf3-a723-4631-a5ce-77f409e54a46", "defaultCacheSize":1, "deviceName":"DataQueueReceiver", "discardExtremeValues":false, "discardHighLimit":1.7976931348623157E308, "discardLowLimit":-1.7976931348623157E308, "intervalLoggingPeriod":15, "intervalLoggingSampleWindowSize":0, "overrideIntervalLoggingSamples":false, "preventSetExtremeValues":false, "purgeOverride":false, "purgePeriod":1, "readPermission":"", "setExtremeHighLimit":1.7976931348623157E308, "setExtremeLowLimit":-1.7976931348623157E308, "setPermission":"", "tags":{ }, "textRenderer":{ "type":"PLAIN", "useUnitAsSuffix":true, "unit":"", "renderedUnit":"", "suffix":"" }, "tolerance":0.0 }, { "xid":"DP_60527aba-6569-451a-91a7-9b1c1c940811", "name":"Queue Timestamp Tracker", "enabled":true, "loggingType":"ON_CHANGE", "intervalLoggingPeriodType":"MINUTES", "intervalLoggingType":"INSTANT", "purgeType":"YEARS", "pointLocator":{ "dataType":"BINARY", "contextUpdate":false, "settable":true, "varName":"tracker" }, "eventDetectors":[ ], "plotType":"STEP", "rollup":"NONE", "unit":"", "templateXid":"Binary_Default", "simplifyType":"NONE", "chartColour":"", "chartRenderer":{ "type":"TABLE", "limit":10 }, "dataSourceXid":"DS_306b3fdc-b914-4187-9a4c-0024be71d52e", "defaultCacheSize":1, "deviceName":"DataQueueProcessor", "discardExtremeValues":false, "discardHighLimit":1.7976931348623157E308, "discardLowLimit":-1.7976931348623157E308, "intervalLoggingPeriod":15, "intervalLoggingSampleWindowSize":0, "overrideIntervalLoggingSamples":false, "preventSetExtremeValues":false, "purgeOverride":false, "purgePeriod":1, "readPermission":"", "setExtremeHighLimit":1.7976931348623157E308, "setExtremeLowLimit":-1.7976931348623157E308, "setPermission":"", "tags":{ }, "textRenderer":{ "type":"BINARY", "oneColour":"black", "oneLabel":"one", "zeroColour":"blue", "zeroLabel":"zero" }, "tolerance":0.0 }, { "xid":"DP_BaseQueueProcessorNumeric", "name":"Base Numeric Sensor Point", "enabled":false, "loggingType":"ALL", "intervalLoggingPeriodType":"MINUTES", "intervalLoggingType":"AVERAGE", "purgeType":"YEARS", "pointLocator":{ "dataType":"NUMERIC", "contextUpdate":false, "settable":true, "varName":"notEnabledBaseDataPoint" }, "eventDetectors":[ ], "plotType":"SPLINE", "rollup":"NONE", "unit":"", "templateXid":"Numeric_All_Data", "simplifyType":"NONE", "chartColour":"", "chartRenderer":{ "type":"IMAGE", "timePeriodType":"DAYS", "numberOfPeriods":1 }, "dataSourceXid":"DS_306b3fdc-b914-4187-9a4c-0024be71d52e", "defaultCacheSize":1, "deviceName":"DataQueueProcessor", "discardExtremeValues":false, "discardHighLimit":1.7976931348623157E308, "discardLowLimit":-1.7976931348623157E308, "intervalLoggingPeriod":1, "intervalLoggingSampleWindowSize":0, "overrideIntervalLoggingSamples":false, "preventSetExtremeValues":false, "purgeOverride":false, "purgePeriod":1, "readPermission":"", "setExtremeHighLimit":1.7976931348623157E308, "setExtremeLowLimit":-1.7976931348623157E308, "setPermission":"", "tags":{ }, "textRenderer":{ "type":"ANALOG", "useUnitAsSuffix":true, "unit":"", "renderedUnit":"", "format":"0.00" }, "tolerance":0.0 } ] } Choosing space and the letter z for my value delimiters was arbitrary (but saved me some HTTP encoding in my nc testing by hand). You can use anything properly query-string-encoded as your delimiters except the @ which is used when timestamps are transmitted. You would just need to adjust the script accordingly. Also I should mention there's an outstanding issue where HTTP receivers don't get messages coming in over IPv6. This means prefer 127.0.0.1 to localhost, as localhost may be ::1 and get bounced by the whitelist. https://github.com/infiniteautomation/ma-core-public/issues/107 Sounding like a reasonable direction?
  • Suddenly lost ability to see Sources yet system continues to run OK

    3
    0 Votes
    3 Posts
    2k Views
    M
    That did it. Thanks.
  • BacNet IP not connected

    9
    0 Votes
    9 Posts
    6k Views
    phildunlapP
    You want to read the logBuffer property, I guess. I didn't test this script (I don't have a BACnet device with a trend log on hand), but I adapted it from this thread to print the LogRecord objects in the 'logBuffer' property of Trend Log object number 1: https://forum.infiniteautomation.com/topic/3117/bacnet-scheduler //Get the local device config from a configured bacnet data source. //Edit DS XID var localDeviceConfig = com.serotonin.m2m2.db.dao.DataSourceDao.instance.getByXid("DS_354e2188-4867-431b-9051-bca39b011ed7").getLocalDeviceConfig(); localDeviceConfig = com.serotonin.ma.bacnet.device.LocalDeviceDwr.getLocalDevice(localDeviceConfig); var listener = new com.serotonin.ma.bacnet.ScriptableDeviceEventListener(); listener.registerListenerExceptionHandler( function(excp) { print("Listener Exception"); }); listener.registerIAmReceivedHandler( function(removeDevice) {print("Remote device");}); listener.registerAllowPropertyWriteHandler( function(from, obj, pv) {print("Allow property write");}); listener.registerPropertyWrittenHandler( function(from, obj, pv) {print("Property written");}); listener.registerIHaveReceivedHandler( function(removeDevice, removeObject) {print("I have received");}); listener.registerCovNotificationReceivedHandler( function(subIdentifier, initDeviceIdentifier, monitoredObjectIdentifier, timeRemaining, listOfValues) {print("COV notification");}); listener.registerEventNotificationReceivedHandler( function(processIdentifier, initDeviceIdentifier, eventObjectIdentifier, timestamp, notificationClass, priority, eventType, messageText, notifyType, ackRequired, fromState, toState, eventValues) {print("Register event notification received");}); listener.registerTextMessageReceivedHandler( function(textMessageSourceDevice, messageClass, messagePriority, message) {print("Text message received");}); listener.registerSynchronizeTimeHandler( function(from, dateTime, utc) {print("Sync time received");}); listener.registerRequestReceivedHandler( function(from, service) {print("Request received");}); var localDevice = com.serotonin.ma.bacnet.device.LocalDeviceFactory.getLocalDevice(localDeviceConfig, listener); //print(localDevice); try { //Create the read request... See com.serotonin.bacnet4j.type.enumerated.ObjectType for object types var objectIdentifier = new com.serotonin.bacnet4j.type.primitive.ObjectIdentifier(com.serotonin.bacnet4j.type.enumerated.ObjectType.trend Log, 1); //EDIT: object instance number var propertyIdentifier = com.serotonin.bacnet4j.type.enumerated.PropertyIdentifier.logBuffer; var readRequest = new com.serotonin.bacnet4j.service.confirmed.ReadPropertyRequest(objectIdentifier, propertyIdentifier); //Get the remote device and send the request, edit the remote device number var remoteDevice = localDevice.getRemoteDeviceBlocking(123); var result = localDevice.send(remoteDevice, readRequest).get(); //result should be a read service ack that we can hopefully get a com.serotonin.bacnet4j.type.constructed.BACnetArray of com.serotonin.bacnet4j.type.constructed.LogRecord from var logRecords = result.getValue(); //now iterate this list and do what for(var k = 0; k < logRecords.size(); k+=1) { print(logRecords.get(k).toString()); } } finally { com.serotonin.ma.bacnet.device.LocalDeviceFactory.releaseLocalDevice(localDevice, listener); } You may need to edit the data source xid, object instance number, and remote device id, as noted in the comments.
  • Problem with initial Mango login - never get the login screen

    11
    0 Votes
    11 Posts
    3k Views
    phildunlapP
    Certainly! Thanks for providing so much information!
  • Mango API: "connectivity lost, restoring connection"

    3
    0 Votes
    3 Posts
    2k Views
    D
    After my attempt to shut down the MangoES and reboot it, now I see magic, It works! It is a false alarm and thank you @CraigWeb for your fast response.
  • Mango persistent TCP

    3
    0 Votes
    3 Posts
    2k Views
    CraigWebC
    @Brad_GMI Seems like only the publisher has a connection lost event. I think ill set up a 'hasn't changed' event on one of my data points. Unfortunately the publisher event is not as reliable as they are normally in the field and are more prone to loosing their internet connection.
  • 100% CPU after user login attempt

    10
    0 Votes
    10 Posts
    3k Views
    phildunlapP
    I have a suspicion the data source page issue would be the one in this thread, with the course of resolution I suspect you will use provided by Jared at the end (unless you are going to upgrade the instance): https://forum.infiniteautomation.com/topic/3551/data-sources-does-not-appear The problem was more pronounced on the publisher, but I could see how points being updated could cause that. I would really consider moving your installation to MySQL, since you are on 2.8 and MySQL doesn't have the issue.
  • Too many daily events java.net.SocketException: Connection reset

    8
    0 Votes
    8 Posts
    3k Views
    CraigWebC
    The protocol limits the device response to 255 bytes, 5 bytes are used for overhead. Leaving 250 bytes for the data. 250 bytes = 125 registers. so use the default values of 125 for read and 120 for write.
  • Excel Report created but not visible

    3
    0 Votes
    3 Posts
    1k Views
    phildunlapP
    Hi etantonio, That null pointer exception wouldn't crash Mango. So, something else must be in your logs, or there may be an hs_err file in your Mango/ directory.. I am not sure what caused it, but the report's filename must be null. You can check to see if the report was actually generated by checking the Mango/web/modules/excelReports/web/report-data/ directory. If you find the right report, you can try to update the row in the database for the report instance that is causing the null pointer exception, or you can delete those report instances since you found the generated files. /sqlConsole.shtm Find and update the reports' records (run whichever line individually): SELECT * FROM excelReports WHERE filename IS NULL; --submit query UPDATE excelReports SET filename='Filename_here.xlsx' WHERE filename IS NULL; --submit update -- use "WHERE id IN (1, 2, 3)" gotten from the select statement if you have more than one type of report) Or just delete those excel report instances with DELETE FROM excelReports WHERE filename IS NULL; -- submit update