Help a newbie figure out time-related functions.
-
@mkart-vrn Welcome Mike!
Apologies for the late reply, it's been a hectic week as the year starts winding upMost of it makes sense, but I'm stuck on dealing with time data. I can't figure out how to set up a page with a simple on/off switch (Start/Stop),
On and off can be implemented using a binary virtual data point and simply toggling it on and off with a toggle switch component.
and three fields for showing start time, stop time, and uptime, even during those Start/Stop switches.
Is this uptime you speak of the total cumulative time that the switch has been on? Or the uptime of the mango system itself? If it's the former, you'll need to set the actual start time you're counting from. No point saying I want to count when the timer is reset every time you hit the off button!
oh, I also want to show the Duration, both in time format and as a plain old integer counting seconds.
This here can be done looking at the maMoment filter with the diff function and duration function, the integer can be implemented in the maMoment filter by combining it with duration and appending with the
| 'as' : 'seconds'
filter.If you start getting more complex the filters and angularJS into the dashboard pages won't be enough and you're going to need a dedicated controller or component to handle these things.
I'm also wanting to know if you're only using this page to display changes on that instance of the page being loaded. If you wish to retain the duration history etc in mango then we will need more numeric/alphanumeric points (depends on where this is going) and you're gonna need a crash course on angularJS!Fox
-
Thank you for your response! Over time, I have made significant progress in learning the tools and solving the problem. Currently, I am working on creating the final version of the demo page and would like to ask you to evaluate the correctness and effectiveness of the methods used. Thanks.
Mike -
@mkart-vrn by all means.
If you are able to copy the markup and paste it into this forum with the code </> block that'd be ideal.
More than happy to help you since you've made a head start.Fox
-
I finally solved my problem.
The page is working, all the required results have been obtained. However, I can't remove the extra 1 in the number of days when displaying Duration. How can this be done?
And I would very much like to understand how correct and optimal the methods I applied.
To start a page, paste next text into a blank new page in the page editor in mango<div class="ma-designer-root" id="11c26dc1-8e3d-475e-ba22-1b6d9c37eb0c" style="width: 1366px; height: 768px; position: relative; background-color: rgb(204, 204, 255);"> <ma-get-point-value point-xid="startTime" point="_startTime"></ma-get-point-value> <ma-get-point-value point-xid="stopTime" point="_stopTime"></ma-get-point-value> <ma-get-point-value point-xid="Start" point="_Start"></ma-get-point-value> <ma-switch id="0022dde1-a203-4176-a0eb-9b120feb36a3" style="position: absolute; left: 220px; top: 60px; font-weight: bold; font-family: fantasy; text-align: center; width: 100px; height: 70px; background-color: rgb(153, 153, 255); color: rgb(0, 0, 0);" display-type="switch" point="Start" label="NAME" point-xid="Start" ng-click="_Start.value ? (_stopTime.setValue(_stopTime.time)) : (_startTime.setValue(_startTime.time))">Start</ma-switch> <ma-now update-interval="1 SECONDS" output="time" browser-timezone="browserTz"></ma-now> <div id="7ebdece1-8366-4df8-b660-62c0c19da235" style="position: absolute; left: 10px; top: 10px; width: 170px; height: 30px; font-weight: normal; line-height: 13px; font-size: 20px; font-family: fantasy;">{{time|maMoment:'format':' DD.MM.YY HH:mm:ss '}}</div> <div id="b554c70c-e4ab-49f8-89be-0b1348180c96" style="position: absolute; left: 370px; top: 70px; width: 210px; height: 30px;">Start time: {{_startTime.value|maMoment:'format':' DD.MM.YY HH:mm:ss '}}</div> <div id="55e794bb-b763-4d59-b2c7-b03bfac43d87" style="position: absolute; left: 370px; top: 100px; width: 210px; height: 30px;" ng-show="_Start.value === false">Stop time :{{_stopTime.value|maMoment:'format':' DD.MM.YY HH:mm:ss '}}</div> <div id="36cc40c9-66d1-4369-9b29-b18edf4cb066" style="position: absolute; left: 670px; top: 90px; width: 210px; height: 30px;" ng-show="_Start.value === false">{{(_stopTime.value-_startTime.value)/1000}}{{"sec = "}} {{((_stopTime.value-_startTime.value))|maMoment:'tz':'UTC'|maMoment:'format':'DDDD[day] HH:mm:ss '}}</div> <ma-indicator id="af49567e-6576-49f5-9bdd-8d8808324cbc" style="position: absolute; width: 30px; height: 30px; left: 330px; top: 80px;" color-false="#ff0000" color-true="#00f500" toggle-on-click="true" point="_Start"></ma-indicator> <div id="fe605657-ed93-4361-9755-7d4ff023ed1f" style="position: absolute; left: 670px; top: 90px; width: 140px; height: 30px;" ng-show="_Start.value">{{(_stopTime.time-_startTime.value)/1000}}sec</div> <div id="fffc771a-27b3-463b-b464-fdaf9db2841d" style="position: absolute; left: 590px; top: 90px; width: 150px; height: 30px;">Duration:</div> </div>
and import the file export_Time_Demo.json into Data integration->Configuration Import/Export.
Looking forward to your comments. Thank you. -
@mkart-vrn
Well I've gottat say you don't look like a newbie. you appear to have a lot of the frontend stuff downpat.
My approach would have been a single binary virtual point for your start and stop switch.
The start time and stop time would be datapoints points inside a scripted datasource (however you could simply just store all three points here and make the switch act as a context point).
The way you have it at the moment. the ng-click event will fire straight away and carry out an action based upon the switch's value.
This is fine if you are hosting locally. Put some delay in there between the client and the mango instance, and you'll have false readings.
The scripting datasource with the switch as a context datapoint firing on change or on updated (if you've got the switch only registering on value changes, then that will handle things nicely).
Then based upon the value, you can set the appropriate start/stop datapoint with the desired value with some simple javascript logic.Secondly, when you create datapoints, you'll need to set the logging type to all, not interval. This is especially crucial if you're trying to capture down to the hundredth millisecond and your interval logging only records the average value every minute..
This in turn means you'll only see on the screen what's in the mango cache - but this does not mean that this will be the recorded value unless you set logging to all data.
Finally, for your duration, use the maDuration filter:{{stopTime.time | maMoment:'diff':_startTime.time|maMoment|maDuration:'as':'seconds'}}
Hope that shines some light on your approach.
Happy to help dig deeperFox
-
Thanks for your answer and advice! Intuitively, I understood that it would be more correct to implement all actions in the system through scripts. But, unfortunately, I cannot find examples of solving any problems using scripts. I managed to figure out a little how to use scripts to handle events. But I absolutely cannot figure out how to use the script data points. I don't understand when these scripts are executed? Only by cron? How to process a button click in it? Is there an example somewhere using the script data points? I've tried many times to read the mango documentation about using script data points and meta data points, but without working examples I can't figure out how to use them.
-
@mkart-vrn scripts can be fired either by a scheduled time, or by context points. Context points are data points that trigger a script run based upon fhe setting of a data point's value being logged, updated, or changed.
I'll get something together based off of your dashboard with the scripting datasource used instead of the ui for youFox
-
This post is deleted! -
Thanks for such a quick response!
Context points are data points that trigger a script run based upon fhe setting of a data point's value being logged, updated, or changed.
I can do something similar through a script in an event handler. But I just can’t figure out how to run a data point script on such events.
I'll get something together based off of your dashboard with the scripting datasource used instead of the ui for you
I would really appreciate your help!
Thank you! -
@mkart-vrn Apologies for the delay. As promised here is the markup and export of the scripting datasource.
Page Markup:
<div class="ma-designer-root" id="11c26dc1-8e3d-475e-ba22-1b6d9c37eb0c" style="width: 1366px; height: 768px; position: relative; " > <ma-get-point-value point-xid="startTime" point="_startTime"></ma-get-point-value> <ma-get-point-value point-xid="stopTime" point="_stopTime"></ma-get-point-value> <ma-get-point-value point-xid="Start" point="_Start"></ma-get-point-value> <ma-get-point-value point-xid="formattedDuration" point="formattedDurationPt" ></ma-get-point-value> <ma-switch id="0022dde1-a203-4176-a0eb-9b120feb36a3" style="position: absolute; left: 220px; top: 60px; font-weight: bold; font-family: fantasy; text-align: center; width: 100px; height: 70px; background-color: rgb(153, 153, 255); color: rgb(0, 0, 0);" display-type="switch" point="_Start" label="NAME" ng-click=>Start</ma-switch> <ma-now update-interval="1 SECONDS" output="time" browser-timezone="browserTz"></ma-now> <div id="7ebdece1-8366-4df8-b660-62c0c19da235" style="position: absolute; left: 10px; top: 10px; width: 170px; height: 30px; font-weight: normal; line-height: 13px; font-size: 20px; font-family: fantasy;">{{time|maMoment:'format':' DD.MM.YY HH:mm:ss '}}</div> <div id="b554c70c-e4ab-49f8-89be-0b1348180c96" style="position: absolute; left: 370px; top: 70px; width: 210px; height: 30px;">Start time: {{_startTime.time|maMoment:'format':' DD.MM.YY HH:mm:ss '}}</div> <div id="55e794bb-b763-4d59-b2c7-b03bfac43d87" style="position: absolute; left: 370px; top: 100px; width: 210px; height: 30px;" ng-show="_Start.value == false">Stop time :{{(_stopTime.time)|maMoment:'format':' DD.MM.YY HH:mm:ss '}}</div> <div id="36cc40c9-66d1-4369-9b29-b18edf4cb066" style="position: absolute; left: 670px; top: 90px; width: 210px; height: 30px;" ng-show="_Start.value == false">{{_stopTime.time | maMoment:'diff':_startTime.time|maDuration:'as':'seconds'}}{{"sec = "}} {{formattedDurationPt.value}}</div> <!--|maDuration:'as':'hours'DD [day] HH:mm:ss '}}--> <ma-indicator id="af49567e-6576-49f5-9bdd-8d8808324cbc" style="position: absolute; width: 30px; height: 30px; left: 330px; top: 80px;" color-false="#ff0000" color-true="#00f500" toggle-on-click="true" point="_Start"></ma-indicator> <div id="fe605657-ed93-4361-9755-7d4ff023ed1f" style="position: absolute; left: 670px; top: 90px; width: 140px; height: 30px;" ng-show="_Start.value">{{(time|maMoment:'diff':_startTime.time|maMoment|maDuration:'as':'seconds')}} sec</div> <div id="fffc771a-27b3-463b-b464-fdaf9db2841d" style="position: absolute; left: 590px; top: 90px; width: 150px; height: 30px;">Duration:</div> </div>
Export of scripting datasource:
{ "dataSources":[ { "xid":"DS_4c94a9ca-5945-47a3-b769-d03ec7bee8fc", "name":"Stopwatch script", "enabled":true, "type":"SCRIPTING", "alarmLevels":{ "SCRIPT_ERROR":"URGENT", "CONTEXT_POINT_DISABLED":"IGNORE", "DATA_TYPE_ERROR":"URGENT", "POLL_ABORTED":"URGENT", "LOG_ERROR":"URGENT" }, "purgeType":"YEARS", "updatePeriods":1, "updatePeriodType":"MINUTES", "updateEvent":"CHANGE", "context":[ ], "logLevel":"NONE", "scriptPermissions":[ "superadmin" ], "polling":false, "executionDelaySeconds":0, "historicalSetting":false, "logCount":5, "logSize":1.0, "script":"var TIMESTAMP = CONTEXT.getTimestamp(); \/\/ Get ts of when script triggered to match when switch was fired\nvar SECONDS = 1000; \/\/ 1000ms\nvar MINUTE_SECONDS = SECONDS * 60; \/\/ 1000ms x 60s\nvar HOUR_SECONDS = MINUTE_SECONDS * 60; \/\/ 1000ms x 60s x 60min\nvar DAY_SECONDS = HOUR_SECONDS * 24; \/\/ 1000ms x 60s x 60min x 24hr\n\nvar days=0,hours=0,mins=0,sec=0; \n\n\nif ( start.value===true )\n{\n startTime.set(TIMESTAMP,TIMESTAMP)\n}\nif ( start.value===false )\n{\n stopTime.set(TIMESTAMP,TIMESTAMP)\n var diff = (TIMESTAMP-startTime.time);\n var formattedStr = \"\";\n\n if(diff>DAY_SECONDS)\n {\n days = Math.floor(diff \/ DAY_SECONDS); \/\/get whole days\n diff = diff % DAY_SECONDS; \/\/ get remainder\n }\n formattedStr += days+\" Days \";\n if(diff>HOUR_SECONDS)\n {\n hours = Math.floor(diff \/ HOUR_SECONDS);\n diff = diff % HOUR_SECONDS;\n }\n formattedStr += hours<10?\"0\"+hours:hours;\n if(diff>MINUTE_SECONDS)\n {\n mins = Math.floor(diff \/ MINUTE_SECONDS);\n diff = diff % MINUTE_SECONDS;\n }\n formattedStr += \":\";\n\n formattedStr += mins<10?\"0\"+mins:mins;\n\n if(diff>SECONDS)\n {\n sec = diff \/ SECONDS;\n\n }\n \n formattedStr += \":\";\n formattedStr += sec<10?\"0\"+sec:sec;\n\n\n formattedDuration.set(formattedStr)\n}\n\n \n ", "quantize":false, "useCron":false, "editPermission":"superadmin", "purgeOverride":false, "purgePeriod":1 } ], "dataPoints":[ { "xid":"Start", "name":"Start", "enabled":true, "loggingType":"ALL", "intervalLoggingPeriodType":"MINUTES", "intervalLoggingType":"INSTANT", "purgeType":"YEARS", "pointLocator":{ "dataType":"BINARY", "contextUpdate":true, "settable":true, "varName":"start" }, "eventDetectors":[ ], "plotType":"STEP", "rollup":"NONE", "unit":"", "simplifyType":"NONE", "chartColour":"", "chartRenderer":{ "type":"TABLE", "limit":10 }, "dataSourceXid":"DS_4c94a9ca-5945-47a3-b769-d03ec7bee8fc", "defaultCacheSize":1, "deviceName":"Stopwatch script", "discardExtremeValues":false, "discardHighLimit":1.7976931348623157E308, "discardLowLimit":-1.7976931348623157E308, "intervalLoggingPeriod":1, "intervalLoggingSampleWindowSize":0, "overrideIntervalLoggingSamples":false, "preventSetExtremeValues":false, "purgeOverride":false, "purgePeriod":1, "readPermission":"user", "setExtremeHighLimit":1.7976931348623157E308, "setExtremeLowLimit":-1.7976931348623157E308, "setPermission":"user", "tags":{ }, "textRenderer":{ "type":"BINARY", "oneColour":"#00ff00", "oneLabel":"ON", "zeroColour":"#0000ff", "zeroLabel":"OFF" }, "tolerance":0.0 }, { "xid":"startTime", "name":"startTime", "enabled":true, "loggingType":"ON_CHANGE", "intervalLoggingPeriodType":"MINUTES", "intervalLoggingType":"AVERAGE", "purgeType":"YEARS", "pointLocator":{ "dataType":"NUMERIC", "contextUpdate":false, "settable":true, "varName":"startTime" }, "eventDetectors":[ ], "plotType":"SPLINE", "rollup":"NONE", "unit":"", "simplifyType":"NONE", "chartColour":"", "chartRenderer":{ "type":"IMAGE", "timePeriodType":"DAYS", "numberOfPeriods":1 }, "dataSourceXid":"DS_4c94a9ca-5945-47a3-b769-d03ec7bee8fc", "defaultCacheSize":1, "deviceName":"Stopwatch script", "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":false, "suffix":"", "format":"0.00" }, "tolerance":0.0 }, { "xid":"stopTime", "name":"stopTime", "enabled":true, "loggingType":"ON_CHANGE", "intervalLoggingPeriodType":"MINUTES", "intervalLoggingType":"INSTANT", "purgeType":"YEARS", "pointLocator":{ "dataType":"NUMERIC", "contextUpdate":false, "settable":true, "varName":"stopTime" }, "eventDetectors":[ ], "plotType":"SPLINE", "rollup":"NONE", "unit":"", "simplifyType":"NONE", "chartColour":"", "chartRenderer":{ "type":"IMAGE", "timePeriodType":"DAYS", "numberOfPeriods":1 }, "dataSourceXid":"DS_4c94a9ca-5945-47a3-b769-d03ec7bee8fc", "defaultCacheSize":1, "deviceName":"Stopwatch script", "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":"ANALOG", "useUnitAsSuffix":false, "suffix":"", "format":"0.00" }, "tolerance":0.0 }, { "xid":"formattedDuration", "name":"formattedDuration", "enabled":true, "loggingType":"ON_CHANGE", "intervalLoggingPeriodType":"MINUTES", "intervalLoggingType":"INSTANT", "purgeType":"YEARS", "pointLocator":{ "dataType":"ALPHANUMERIC", "contextUpdate":false, "settable":true, "varName":"formattedDuration" }, "eventDetectors":[ ], "plotType":"STEP", "rollup":"NONE", "unit":"", "simplifyType":"NONE", "chartColour":"", "chartRenderer":{ "type":"TABLE", "limit":10 }, "dataSourceXid":"DS_4c94a9ca-5945-47a3-b769-d03ec7bee8fc", "defaultCacheSize":1, "deviceName":"Stopwatch script", "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":"PLAIN", "useUnitAsSuffix":false, "suffix":"" }, "tolerance":0.0 } ] }
Have a look, let me know if this is closer to what you wanted to achieve
Fox
-
Thanks a lot! Yes, everything works as it should. Now I have almost completely understood the use of scripts.
And there remains one more not completely clear point.
What is a CONTEXT object? Is there a help page for CONTEXT.? What other methods can you use with it?Now I'm solving another problem,
How to execute a script at a precisely specified time from the current moment? How can I cancel its launch during the waiting time?
Are there any other ways to change the value of points after a given time?
Thank you! -
@mkart-vrn there are help docs available. This can be exposed by showing them via the edit menu page and saving the changes. Alternatively, on the scripting datasource page. There are question marks you can click on that will render a sidebar to the right with a detailed explanation and or help docs.
I also encourage you to look through the forum and see what has been accomplished by other mango power users.
As for delays, there is a delay option so you can delay the firing of a script upon a trigger as well as using a cron style scheduler. There's also an advanced scheduler which you can attach event actions to for triggering scripts, running a local application, even setting point values.
Feel free to raise more forum posts in user help to fill in any blank areas. I'm on here throughout the week usually. I'm currently remote however so expect up to week delays...
Fox