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.

  • Sum each minute of parameter each second value

    7
    0 Votes
    7 Posts
    2k Views
    phildunlapP
    to solve the same problem "sample pyrheliometer every second and store each minute the sum of these values in a datapoint" I've tried also a different approach, it is to define a datasource polled each 1 second and then define the DNI point logging as average 1 minute. It's not the same as the original question (sum) to do the average. Note that there is no interval sum interval logging type. Is it right? to avoid calculations on database it is better to choose a cache size of more than 60? That doesn't matter for the interval logging. One can compute a running average from incoming values or the end of an interval. It should also be said the average is time-weighted where the sum / count is not. it seems so but just disabling "show cached data" instead with cached data I've a data each second: You're not showing data from the same time period and they're not computing the same thing. So, I'm not sure what the images of tables of values are supposed to mean.
  • 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
    1k 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
    2k 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
    2k 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
    1k 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
    1k 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
    4k 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
    2k 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
    4k 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
    2k 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
    2k 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
    2k 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.