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 REST API -- how to create Data Sources / Data Points?


  • Hi all,

    I'm trying to create Data Sources and Data Points using Javascript, through the Mango REST API.

    So far I've enabled swagger and I've been checking data-sources (POST method, as I want to create new data sources). I've successfully created a data source using the 'Try it out' button. However, I'm very confused as to how to do it with Javascript.

    Do you have any tutorials or examples, please?

    Thanks so much.


  • Pure JavaScript? Usually someone is using JQuery or Angular and can use their ajax wrappers. In pure JavaScript you will want some familiarity with writing your own XMLHttpRequest based code, but it'll look something like....

    var responseFunc = console.log("Got the response, check the network tab");
    var xmlHttpRequest = new XMLHttpRequest();
    //Because I executed this in the developer tools for a tab I had already logged in with,
    // I did not have to get a Cookie through logging in, that's handled by the browser
    xmlHttpRequest.open("POST", "http://localhost:8080/rest/v1/data-sources");
    xmlHttpRequest.setRequestHeader("Content-Type", "application/json");
    xmlHttpRequest.setRequestHeader("X-Xsrf-Token", "Get this value from a working request on the network tab or handle login")
    xmlHttpRequest.addEventListener("load", responseFunc);
    xmlHttpRequest.send(JSON.stringify({
          "xid": "DS_12345",
          "name": "data",
          "enabled": false,
          "modelType": "VIRTUAL",
          "validationMessages": [],
          "pollPeriod": {
            "periods": 5,
            "type": "SECONDS"
          },
          "polling": false,
          "alarmLevels": {
            "POLL_ABORTED": "URGENT"
          },
          "purgeSettings": {
            "override": false,
            "frequency": {
              "periods": 1,
              "type": "YEARS"
            }
          },
          "editPermission": "",
        }));
    

    Or if you have a JavaScript environment like node.js or are using a library like jQuery there are request wrappers that make this easier,

    //Refer to http://api.jquery.com/jquery.ajax/
    jQuery.ajax("http://localhost:8080/rest/v1/data-sources",
      {
         "method": "POST",
         "contentType": "application/json",
         "headers": { /*"Cookie": "Your cookie here",*/ "X-Xsrf-Token": "Your XSRF Token here" },
         "data": JSON.stringify(/*sameObjectAsAbove*/),
         "success": function(data, status, jqXHR) { if(status == 201) console.log("Created!"); else console.log("Ah snap."); }
      });
    

    Or check mangoObject.js https://github.com/infiniteautomation/node-mango-client/blob/master/src/mangoObject.js for some relevant examples using node.js


  • If you are using Node.js I'd strongly suggest using
    https://github.com/infiniteautomation/node-mango-client

    If you are doing this from a browser I'd suggest using our AngularJS services. You do not have to bootstrap AngularJS to use these. Let me know if you want to go down this path and I'll provide an example.


  • Thanks @phildunlap and @Jared-Wiltshire :)

    I'm using node.js so I will give node-mango-client a go and see how it goes!

    Cheers,

    Silvia


  • Hi again,

    Node-mango-client works like a charm for creating the data sources, thanks! :)

    However, when I'm trying to create a data point, I start by copying the model schema from POST /v1/data-points and defining a couple of parameters.

    {
      "enabled": true,
      "templateXid": "readings",
      "loggingProperties": {
        "tolerance": 0,
        "discardExtremeValues": false,
        "discardLowLimit": 0,
        "discardHighLimit": 0,
        "loggingType": "ALL",
        "intervalLoggingType": "MINUTES",
        "intervalLoggingPeriod": {
          "periods": 1,
          "type": "MINUTES"
        },
        "overrideIntervalLoggingSamples": false,
        "intervalLoggingSampleWindowSize": 0,
        "cacheSize": 0
      },
      "textRenderer": {
        "settable": false,
        "relinquishable": false
      },
      "chartRenderer": {
        "settable": false,
        "relinquishable": false
      },
      "modelType": "",
      "validationMessages": [
        {
          "message": "",
          "level": "",
          "property": ""
        }
      ],
      "id": 0,
      "dataSourceId": 0,
      "readPermission": "",
      "setPermission": "",
      "chartColour": "",
      "rollup": "NONE",
      "plotType": "LINE",
      "purgeOverride": false,
      "purgePeriod": {
        "periods": 1,
        "type": "YEARS"
      },
      "pointLocator": {
        "settable": false,
        "relinquishable": false
      },
      "deviceName": "socket 1743",
      "dataSourceXid": "SK1743",
      "useIntegralUnit": false,
      "useRenderedUnit": true,
      "unit": "kW",
      "renderedUnit": "kW",
      "integralUnit": "",
      "dataSourceName": "socket_1743",
      "name": "reading",
      "xid": "sk1743_r"
    }
    

    To make it easy, I copy this into the 'body' and I use the 'Try it Out' button, but it returns an error 400.

    Response Code

    400
    

    Response Body

    {
      "message": null,
      "stackTrace": "com.serotonin.m2m2.web.mvc.rest.v1.mapping.SuperclassModelDeserializer.deserialize(SuperclassModelDeserializer.java:49)\ncom.serotonin.m2m2.web.mvc.rest.v1.mapping.SuperclassModelDeserializer.deserialize(SuperclassModelDeserializer.java:25)\ncom.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:499)\ncom.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:101)\ncom.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:357)\ncom.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:148)\ncom.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3798)\ncom.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2922)\norg.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:237)\norg.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:225)\norg.springframework.web.servlet.mvc.method.annotation.AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters(AbstractMessageConverterMethodArgumentResolver.java:201)\norg.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.readWithMessageConverters(RequestResponseBodyMethodProcessor.java:150)\norg.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor.resolveArgument(RequestResponseBodyMethodProcessor.java:128)\norg.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121)\norg.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:158)\norg.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128)\norg.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:116)\norg.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)\norg.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)\norg.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)\norg.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963)\norg.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897)\norg.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)\norg.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)\njavax.servlet.http.HttpServlet.service(HttpServlet.java:707)\norg.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)\njavax.servlet.http.HttpServlet.service(HttpServlet.java:790)\norg.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:845)\norg.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1689)\norg.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197)\norg.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)\norg.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1676)\norg.springframework.web.filter.ShallowEtagHeaderFilter.doFilterInternal(ShallowEtagHeaderFilter.java:110)\ncom.serotonin.m2m2.web.filter.MangoShallowEtagHeaderFilter.doFilterInternal(MangoShallowEtagHeaderFilter.java:80)\norg.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)\norg.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1676)\norg.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:317)\norg.springframework.security.web.authentication.switchuser.SwitchUserFilter.doFilter(SwitchUserFilter.java:198)\norg.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)\norg.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)\norg.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)\norg.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)\ncom.serotonin.m2m2.web.mvc.spring.security.PermissionExceptionFilter.doFilter(PermissionExceptionFilter.java:32)\norg.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)\norg.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:115)\norg.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)\norg.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)\norg.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)\norg.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)\norg.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)\norg.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:169)\norg.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)\norg.springframework.security.web.session.ConcurrentSessionFilter.doFilter(ConcurrentSessionFilter.java:134)\norg.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)\norg.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)\norg.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)\norg.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:121)\norg.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)\norg.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:124)\norg.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)\norg.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)\norg.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)\norg.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)\norg.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)\norg.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)\norg.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)\norg.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)\norg.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)\norg.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331)\norg.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:214)\norg.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)\norg.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:346)\norg.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:262)\norg.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1668)\norg.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:581)\norg.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)\norg.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:548)\norg.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226)\norg.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1180)\norg.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:511)\norg.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)\norg.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112)\norg.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)\norg.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:213)\norg.eclipse.jetty.server.handler.gzip.GzipHandler.handle(GzipHandler.java:397)\norg.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)\norg.eclipse.jetty.server.Server.handle(Server.java:524)\norg.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:319)\norg.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:253)\norg.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:273)\norg.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:95)\norg.eclipse.jetty.io.SelectChannelEndPoint$2.run(SelectChannelEndPoint.java:93)\norg.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.executeProduceConsume(ExecuteProduceConsume.java:303)\norg.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.produceConsume(ExecuteProduceConsume.java:148)\norg.eclipse.jetty.util.thread.strategy.ExecuteProduceConsume.run(ExecuteProduceConsume.java:136)\norg.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:671)\norg.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:589)\njava.lang.Thread.run(Thread.java:748)\n"
    }
    

    Response Headers

    {
      "Date": "Wed, 08 Nov 2017 15:58:26 GMT",
      "X-Content-Type-Options": "nosniff",
      "X-Frame-Options": "SAMEORIGIN",
      "Content-Type": "application/json;charset=utf-8",
      "Cache-Control": "no-cache, no-store, max-age=0, must-revalidate",
      "Messages": "error",
      "Content-Length": "10009",
      "X-Xss-Protection": "1; mode=block"
    }
    

    The model from the REST API also makes me wonder how to define the data type in the pointLocator object, and the type and units in textRenderer. Also, in the case of multistate points, how to define the multistateValues and event detectors?

    I thought it would be as simple as copying the export JSON from the data point...

    Thanks again for your time.


  • Hi Silvia,

    The generated model textbox on the swagger page is not the easiest thing to start with and adapt to requests. I find if you use the GET endpoint to get a similar point that you've configured through the regular UI how you'd like it to be, you get the best base of JSON to work with for that point type. You'll need to remove the ID and change the XID to create a new point with its JSON.


  • Wonderful!!!

    It works perfectly :D

    Thanks @phildunlap