• cbyrne

    @phildunlap Thanks Phil! The naming was just for show, it's named differently in our system for the exact reason you gave. Thanks for the note about permissions, fixed now.

    posted in User help read more
  • cbyrne

    Finally got a working solution. Posted the basic custom module below for anyone else who comes across this thread.

    define(['angular', 'require'], function(angular, require) {
    'use strict';
    
    var userModule = angular.module('userModule', ['maUiApp']);
    
    userModule.component('userComponent', {
        bindings: {},
        controller: ['$scope', '$http', 
            function($scope, $http){
                $scope.msg = null;
                $scope.sendPost = function(point_xid, date_from, date_to, email_recipients){
                    var from = JSON.stringify(date_from);
                    var to = JSON.stringify(date_to);
                    var emails = JSON.stringify(email_recipients);
                    var script = "send_HTTP_debug(point_xid, " + from + ", " + to + ", " + emails + ")"
    
                    var address= "/rest/v2/script/run";
                    var content = {'Content-Type': 'application/json;charset=UTF-8'};
                    var data = {
                          "context": [
                            {
                              "contextUpdate": true,
                              "variableName": "point_xid",
                              "xid": point_xid
                            },
                          ],
                          "logLevel": "DEBUG",
                          "permissions": [
                            "admin"
                          ],
                          "script": script,
                          "wrapInFunction": true
                    };
                    function success(response){$scope.msg=response;};
                    function error(response){$scope.msg=response;};
    
                    $http.post(address, JSON.stringify(data),content).then(success, error);
                };
            }],
        template: '\
        <div flex layout="column">\
            <md-input-container md-no-float="">\
                <label>Point</label>\
                <ma-point-list ng-model="point" query="query_tmpVal" start="start_tmpVal" limit="limit_tmpVal" sort="sort_tmpVal"></ma-point-list>\
            </md-input-container>\
            <div flex layout="row">\
                <md-input-container style="flex-grow:1">\
                <label>From</label>\
                    <ma-date-picker ng-model="date_from" mode="date" format="DD/MM/YYYY"></ma-date-picker>\
                </md-input-container>\
                <div style="width="10vw">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div>\
                <md-input-container style="flex-grow:1">\
                    <label>To</label>\
                    <ma-date-picker ng-model="date_to" mode="date" format="DD/MM/YYYY"></ma-date-picker>\
                </md-input-container>\
            </div>\
            <md-input-container>\
                <ma-email-recipients ng-model="email_recipients"></ma-email-recipients>\
            </md-input-container>\
            <md-button class="md-primary md-raised" ng-click="sendPost(point.xid, date_from, date_to, email_recipients)">Request Report</md-button>\
            <p>{{msg}}</p>\
        </div>\
        '
    });
    
    return userModule;
    
    }); // define
    

    posted in User help read more
  • cbyrne

    @phildunlap After some work I got a little further but I've hit a stumbling block with the POST data spec

    {
      "context": [
        {
          "contextUpdate": true,
          "variableName": "string",
          "xid": "string"
        }
      ],
      "logLevel": "TRACE",
      "permissions": [
        "string"
      ],
      "resultDataType": "string",
      "script": "string",
      "wrapInFunction": true
    }
    

    The global function I want to call is something like send_http(point, start_time, end_time, email_addresses) and I have the four parameters. The point I presume I can send as the context, but I don't know how to send the other parameters.

    posted in User help read more
  • cbyrne

    @phildunlap thanks Phil, could you give me an example of how exactly to call the $http.post request? Sorry, I'm not fluent with angular at all. What I can find online does the whole var app = angular.module... boilerplate but I know I'm already in that context in the dashboard designer so I'm note sure how to define the function as I usually would in a scripting context.

    posted in User help read more
  • cbyrne

    Could anyone tell me how to call a global script from a dashboard?

    The layout would be pretty simple:

    • point selector
    • date range picker
    • email recipients
    • button

    The script takes values from the point selector, date range picker and email recipients. This I know how to do but I just don't know how to call the global script as the on-click action of the button.

    Thanks!

    posted in User help read more
  • cbyrne

    @phildunlap Hey Philip, it's actually the data point copy that throws the error, data source copies just fine. I have observed the same error over two separate installations running 3.6.4

    It also doesn't seem to depend on the data source type.

    posted in User help read more
  • cbyrne

    I'm using Data File sources which are still handled through the legacy UI. From a quick test, I don't think the new UI has this issue.

    Relevant console log:

    ERROR 2019-08-29T17:18:12,275 (com.serotonin.m2m2.web.dwr.util.ExceptionDetectionFilter.doFilter:38) - DWR invocation exception com.serotonin.m2m2.vo.permission.PermissionException: Subclass DWRs must implement method to use 
    at com.serotonin.m2m2.web.dwr.AbstractDwr.getCopy(AbstractDwr.java:182) ~[mango-3.6.4.jar:?] 
    at com.serotonin.m2m2.web.dwr.DataPointDwr.getCopy(DataPointDwr.java:268) ~[mango-3.6.4.jar:?] 
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?] 
    at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[?:?] 
    at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?] 
    at java.lang.reflect.Method.invoke(Method.java:566) ~[?:?] 
    at org.directwebremoting.impl.ExecuteAjaxFilter.doFilter(ExecuteAjaxFilter.java:34) ~[dwr-2.0.11.jar:?] 
    at org.directwebremoting.impl.DefaultRemoter$1.doFilter(DefaultRemoter.java:428) ~[dwr-2.0.11.jar:?] 
    at com.serotonin.m2m2.web.dwr.util.TranslationsFilter.doFilter(TranslationsFilter.java:37) ~[mango-3.6.4.jar:?] 
    at org.directwebremoting.impl.DefaultRemoter$1.doFilter(DefaultRemoter.java:428) ~[dwr-2.0.11.jar:?] 
    at com.serotonin.m2m2.web.dwr.util.ExceptionDetectionFilter.doFilter(ExceptionDetectionFilter.java:26) ~[mango-3.6.4.jar:?] 
    at org.directwebremoting.impl.DefaultRemoter$1.doFilter(DefaultRemoter.java:428) ~[dwr-2.0.11.jar:?] 
    at com.serotonin.m2m2.web.dwr.util.DwrPermissionFilter.doFilter(DwrPermissionFilter.java:46) ~[mango-3.6.4.jar:?] 
    at org.directwebremoting.impl.DefaultRemoter$1.doFilter(DefaultRemoter.java:428) ~[dwr-2.0.11.jar:?] 
    at org.directwebremoting.impl.DefaultRemoter.execute(DefaultRemoter.java:431) ~[dwr-2.0.11.jar:?] 
    at org.directwebremoting.impl.DefaultRemoter.execute(DefaultRemoter.java:283) ~[dwr-2.0.11.jar:?] 
    at org.directwebremoting.servlet.PlainCallHandler.handle(PlainCallHandler.java:52) ~[dwr-2.0.11.jar:?] 
    at org.directwebremoting.servlet.UrlProcessor.handle(UrlProcessor.java:101) ~[dwr-2.0.11.jar:?] 
    at org.directwebremoting.servlet.DwrServlet.doPost(DwrServlet.java:146) ~[dwr-2.0.11.jar:?] 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:707) ~[javax.servlet-api-3.1.0.jar:3.1.0] 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) ~[javax.servlet-api-3.1.0.jar:3.1.0] 
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:865) ~[jetty-servlet-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1655) ~[jetty-servlet-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.springframework.web.filter.ShallowEtagHeaderFilter.doFilterInternal(ShallowEtagHeaderFilter.java:108) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE] 
    at com.serotonin.m2m2.web.filter.MangoShallowEtagHeaderFilter.doFilterInternal(MangoShallowEtagHeaderFilter.java:95) ~[mango-3.6.4.jar:?] 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE] 
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642) ~[jetty-servlet-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.authentication.switchuser.SwitchUserFilter.doFilter(SwitchUserFilter.java:200) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at com.serotonin.m2m2.web.mvc.spring.security.RateLimitingFilter.doFilterInternal(RateLimitingFilter.java:56) ~[mango-3.6.4.jar:?] 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at com.serotonin.m2m2.web.mvc.spring.security.PermissionExceptionFilter.doFilter(PermissionExceptionFilter.java:34) ~[mango-3.6.4.jar:?] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:155) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:100) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:74) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE] 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178) ~[spring-security-web-5.1.5.RELEASE.jar:5.1.5.RELEASE] 
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE] 
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270) ~[spring-web-5.1.7.RELEASE.jar:5.1.7.RELEASE] 
    at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1642) ~[jetty-servlet-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:533) ~[jetty-servlet-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:146) ~[jetty-server-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548) ~[jetty-security-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) ~[jetty-server-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:257) ~[jetty-server-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:1595) ~[jetty-server-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.server.handler.ScopedHandler.nextHandle(ScopedHandler.java:255) ~[jetty-server-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1340) ~[jetty-server-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:203) ~[jetty-server-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:473) ~[jetty-servlet-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:1564) ~[jetty-server-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.server.handler.ScopedHandler.nextScope(ScopedHandler.java:201) ~[jetty-server-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1242) ~[jetty-server-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:144) ~[jetty-server-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:220) ~[jetty-server-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:740) ~[jetty-server-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:132) ~[jetty-server-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.server.Server.handle(Server.java:503) ~[jetty-server-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:364) ~[jetty-server-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:260) ~[jetty-server-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:305) ~[jetty-io-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103) ~[jetty-io-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:118) ~[jetty-io-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:333) ~[jetty-util-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:310) ~[jetty-util-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:168) ~[jetty-util-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:126) ~[jetty-util-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:366) ~[jetty-util-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:765) ~[jetty-util-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:683) ~[jetty-util-9.4.12.v20180830.jar:9.4.12.v20180830] 
    at java.lang.Thread.run(Thread.java:834) [?:?] 
    

    posted in User help read more
  • cbyrne

    @phildunlap Cool cool cool, sounds like a nice solution. Thanks for keeping us in the loop!

    posted in User help read more
  • cbyrne

    @phildunlap Thanks Phil, much appreciated!

    Similarly, would you consider adding a last_value-first value to the mango statistics object?

    There already are the values Start, First, and Last in terms of values. They are formally defined here: https://help.infiniteautomation.com/mango-rollups-and-statistics

    I should have been more specific on what I meant, I mean could the statistics object include a value which is equal to the last value minus the start value for the time period, essentially, the consumption or delta in my terms. For example, on the point details page in the point statistics card, it would be great to have one more value, the delta/consumption. But this is minor to the original issue.

    posted in User help read more
  • cbyrne

    @cwangv
    We import our data from CSV files that are timestamp,value_1...value_n in fomat.
    Maybe I'm misunderstanding but I don't see polling times affecting it.

    posted in User help read more
  • cbyrne

    @cwangv Yeah our polling interval is every 15 minutes.

    posted in User help read more
  • cbyrne

    Hi @phildunlap, thanks for the info, however I think this way of calculating deltas is flawed for anyone doing metered readings. These happen at regular intervals like above and currently the delta value for an hour does not show the user their usage for one hour and this is the critical issue.

    The way the delta is being calculated effectively drops one reading per rollup period and gives a misleading result. The normal approach for metered data at regular intervals is to only allow rollups that are a multiple of the reading interval and to calculate the delta based on the difference between the first reading of each rollup period i.e. for 15 minute readings, an hourly rollup would take the first reading of hour 2 and subtract the first reading of hour 1.

    Ofsetting by 1 ms does not cure the problem as it forces the last reading in the period into the next period so it still gets missed.

    One solution might be to add a "consumption" delta option to use this method? We're trying to push Mango to our customers right now for energy monitoring and this is the behaviour they need and expect. Similarly, would you consider adding a last_value-first value to the mango statistics object? Again, for energy monitoring, this delta is the key piece of information as it's their usage in the time period.

    posted in User help read more
  • cbyrne

    I've got a question in two parts. From looking at some delta data, there seems to be some discrepancy with rollups. This may be a misunderstanding on my part to how the deltas/rollups are calculated. I'm also getting no graph for 15m intervals.


    Part 1

    Sample data for a power usage accumulator:

    timestamp               value
    21/8/2019 05:30:00 	2724.95 kW·h
    21/8/2019 05:15:00 	2722.89 kW·h
    21/8/2019 05:00:00 	2720.82 kW·h
    21/8/2019 04:45:00 	2718.79 kW·h
    21/8/2019 04:30:00 	2717.55 kW·h
    21/8/2019 04:15:00 	2716.30 kW·h
    21/8/2019 04:00:00 	2715.06 kW·h
    21/8/2019 03:45:00 	2713.82 kW·h
    21/8/2019 03:30:00 	2712.57 kW·h
    21/8/2019 03:15:00 	2711.34 kW·h
    21/8/2019 03:00:00 	2710.09 kW·h
    21/8/2019 02:45:00 	2708.84 kW·h
    21/8/2019 02:30:00 	2707.59 kW·h
    21/8/2019 02:15:00 	2706.36 kW·h
    21/8/2019 02:00:00 	2704.24 kW·h
    21/8/2019 01:45:00 	2702.09 kW·h
    21/8/2019 01:30:00 	2699.94 kW·h
    

    If we set the rollup interval to 15m (or 900 seconds) and rollup type to delta, the graph on the data point details page goes blank:

    0_1566482536018_Screenshot_2019-08-22 Data point details - Mango v3.png

    Bug or expected behaviour?


    Part 2:

    For a 30 minute rollup and 60 minute rollup the graphs are as follows:
    1_1566482779667_Screenshot_2019-08-22 Data point details - Mango v3_60.png

    0_1566482779666_Screenshot_2019-08-22 Data point details - Mango v3_30.png

    and the transcribed values are:

    time 30 mins 60 mins
    02:00 2.12 4.6
    02:30 1.25
    03:00 1.24 3.73
    03:30 1.25
    04:00 1.24 3.73
    04:30 1.24

    I would have assumed that the 1 hour delta is the assume as the combined 30 minute deltas but it seems not to be the case.

    posted in User help read more
  • cbyrne

    Amazing, thanks @MattFox. Using your as a guide I managed to get it working.

    One or two questions just for my own knowledge/curiosity.

    1. Difference/benefits of your mod_rewrites vs. my Redirect permanent for the HTTP virtual host? I get that the rewrite happens on the server and the redirect tells the client to send a new request to the redirect URL; but is there a notable benefit of one over the other?

    2. What exactly is happening in the <Proxy *> block?

    posted in User help read more
  • cbyrne

    Actually I spoke too soon, proxying web sockets isn't working yet. I followed your example in the other thread @phildunlap but unfortunately I'm still getting errors. Perhaps my rewrite rule is incorrect for a localhost address?

    0_1565950148266_websock.png

    My config:

    <VirtualHost *:80>
        Redirect permanent / https://ems1.glasenergytechnology.ie/
    </VirtualHost>
    
    Listen 443
    <VirtualHost *:443>
        ProxyPreserveHost Off
        ServerName sub.domain.com
        ServerAlias sub.domain.com
        ProxyRequests On
        RewriteEngine On
        RewriteCond %{HTTP:Upgrade} =websocket
        RewriteRule /(.*) ws://127.0.0.1:8080/$1 [P,L]
        RewriteCond %{HTTP:Upgrade} !=websocket
        RewriteRule /(.*) http://127.0.0.1:8080/$1 [P,L]
        RequestHeader set Host sub.domain.com
        RequestHeader set Origin "http://sub.domain.com"
        Header edit Location ^http://sub.domain.com https://sub.domain.com
        CustomLog "/var/log/apache-access-public-mango.log" common
        ErrorLog "/var/log/apache-error-public-mango.log"
        SSLEngine On
        SSLProxyEngine On
        SSLCertificateFile "/path/to/crt"
        SSLCertificateChainFile "/path/to/ca-bundle"
        SSLCertificateKeyFile "/path/to/private_key"
        ProxyPass / http://127.0.0.1:8080/
        ProxyPassReverse / http://127.0.0.1:8080/
    </VirtualHost>

    posted in User help read more
  • cbyrne

    Perfect, thanks for all your help @terrypacker @MattFox @phildunlap.

    edit:
    @terrypacker Quick question regarding the help article

    0_1565944443039_Screenshot_2019-08-16 Proxy — Infinite Automation Support.png

    Specifically "we set the Host and Origin to the public facing server".
    Isn't "mango.example.com" the private facing address?

    posted in User help read more
  • cbyrne

    All working now. Here's my solution using an Apache proxy as advised by @MattFox.
    Starting with a mango installation running on port 8080 and not handling ssl.

    1. Make sure you have httpd and mod_ssl installed.
    2. Place SSL cert files (your cert, cert bundle and key) in a directory of your choosing.
    3. Check for ssl.conf. Installing mod_ssl created a ssl.conf in /etc/httpd/conf.d/ which I had to disable (I just named it ssl.conf.old). It overrode my SSL settings below and used the packaged self-signed cert.
    4. Make a new config file eg. /etc/httpd/conf.d/mango.conf
    5. Populate is as follows:
    <VirtualHost *:80>
        Redirect permanent / https://subdomain.maindomain.com
    </VirtualHost>
    
    <VirtualHost *:443>
        ProxyPreserveHost On
        SSLEngine On
        SSLCertificateFile "path/to/your.crt"
        SSLCertificateChainFile "/path/to/your.ca-bundle"                               
        SSLCertificateKeyFile "/path/to/your_key"
        ProxyPass / http://127.0.0.1:8080/
        ProxyPassReverse / http://127.0.0.1:8080/
    </VirtualHost>
    
    1. Restart the httpd service.

    If anyone notices any loopholes or things I could add to harden it up please let me know.

    posted in User help read more
  • cbyrne

    @mattfox Thanks Matt, I may well do that. I'll try it in the morning and update this post later on in the day.

    posted in User help read more
  • cbyrne

    Hi guys,

    From following @phildunlap 's instructions in a previous thread, I made my keystore and got mango to use it just fine. So I do have a working https connection to the mango instance.

    The httaccess is on our base webserver, mango lives on a completely separate VPS.

    So the issue isn't with getting SSL working, it does, but rather when redirected to the loop is made.

    In the mean time I'll look into how apache proxy's work as an alternative!

    posted in User help read more
  • cbyrne

    Hey guys, hoping someone can point out my mistake but I am trying to get HTTPS redirecting working but I currently have a redirect loop happening somewhere.

    I have mango running on a VS with ip $IP.
    I have a DNS A record of my main domain pointing a subdomain to $IP.

    Originally I had a rule in .htaccess to send all http to https but I've taken it out for now.

    I've enabled SSL and HSTS in env.properties and accessing the https://subdomain.domain.com works perfectly. However, when accessing http:... for the first time it causes a redirect loop.

    Disabling HSTS and applying a catch-all http -> https rule in .htaccess doesn't seem to work as you end up at http and no redirect seems to occur.

    If you restart mango while HSTS is enabled, you'll get to see the loading screen for mango as it boots up and then at 100% is stays on "mango is running". Then a refresh of the page causes a redirect loop.

    However, if you manually go to the https first, then try the http you will be redirected properly. Clear the cache and go to to http and you'll get the redirect loop again.

    Firefox inspection:
    0_1565795137280_redirect.png

    If anyone has any ideas, that'd be great!

    posted in User help read more