• Recent
    • Tags
    • Popular
    • Register
    • Login

    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 5 Documentation Website

    maJsonStore (JSON store)

    Scripting general Discussion
    4
    35
    14.6k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • CraigWebC
      CraigWeb
      last edited by Jared Wiltshire

      Hi Richard

      The promise variable will have 3 states fulfilled, rejected and pending. It gives you the status of the query. So no is the answer to your question about the promise.

      <ma-point-query query="'eq(tags.SiteName,SPS001)&&(tags.Display,Customer Load)'" points="points" ></ma-point-query>
      

      There is no operatore for your second criteria. This should work

      <ma-point-query query="'eq(tags.SiteName,SPS001)&eq(tags.Display,Customer Load)'" points="points" ></ma-point-query>
      

      As Mattfox sugested useing the watchlist builder to make your RQL queries. Let me show you how. The nice thing about using this method is there is you can see the results immediately on the query preview tab.
      0_1557821191387_untitled (25).png

      As for what you are doing in the table. I think you might be running into scoping issues with using points. Hopefully, @Jared-Wiltshire can comment on that.

      ng-if="points | filter:{tags:'Display'}" Will not work and I'm sure there are plenty of errors in your browser's console when you use this. tags is an object, what you are doing there is filtering the points array for any object that has a tag with a value of string 'Display'

      As in my previous post if you want to filter with tags you need to supply a nested object the filter ie:

      point="points | filter:{tags:{Display: 'Battery Capacity'} }"
      

      If you want to use it in a ng-if you need to use maFirst

      point="points | filter:{tags:{Display: 'Battery Capacity'} | maFirst}"
      

      Lastly, I think that your pages are getting quite complex and you would be better off creating a user module where you have a controller to do all your logic and mapping of arrays,

      richard.mortimerR 1 Reply Last reply Reply Quote 0
      • richard.mortimerR
        richard.mortimer @CraigWeb
        last edited by

        @craigweb said in maJsonStore (JSON store):

        Hi Richard

        There is no operatore for your second criteria. This should work

        <ma-point-query query="'eq(tags.SiteName,SPS001)&eq(tags.Display,Customer Load)'" points="points" ></ma-point-query>
        

        Thanks - that was the syntax I was after; I couldn't see anything like i in the RQL syntax: https://cubicweb.readthedocs.io/en/3.26/book/annexes/rql/language/#rql

        Is there somewhere that I can read about this??

        Also I note that in my nested repeats, this will work, and display all the relevant info for a single point:

        <ma-json-store xid="sitesDataXID" value="sites"></ma-json-store>
        <div style="border:2px solid blue;" ng-repeat="site in sites.sites">
            <ma-point-query query="'eq(tags.SiteName,SPS001)&eq(tags.Display,Customer Load)'" points="points" ></ma-point-query>
            <!-- show me everything -->
            <div style="color: white;background-color:black; border: 1px solid red;">--{{ site.name }}--<pre>{{ points }}</pre>--</div>
        </div>
        

        0_1557900229406_cycle1.png

        Yet if I change the tag.SiteName to {{site.name}} thus:

        <ma-json-store xid="sitesDataXID" value="sites"></ma-json-store>
        <div style="border:2px solid blue;" ng-repeat="site in sites.sites">
            <ma-point-query query="'eq(tags.SiteName,{{site.name}})&eq(tags.Display,Customer Load)'" points="points" ></ma-point-query>
            <!-- show me everything -->
            <div style="color: white;background-color:black; border: 1px solid red;">--{{ site.name }}--<pre>{{ points }}</pre>--</div>
        </div>
        

        I'm getting this:

        0_1557900459270_cycle2.png

        Although the browsers (Firefox) code inspector displays the code as it should:

        0_1557901439677_cycle3.png

        So - should that work as I have it, or does Angular not allow variable substitution in this manner? I al;so tried to do it with ' + {{site.name}} + ' and a few variations (but clearly not the right one!)

        ng-if="points | filter:{tags:'Display'}" Will not work and I'm sure there are plenty of errors

        My apologies - I left this in with changing the page so much ...

        As Mattfox sugested useing the watchlist builder to make your RQL queries. Let me show you how. The nice thing about using this method is there is you can see the results immediately on the query preview tab.

        Thanks for that - I'm looking into how that all works ...

        Cheers

        Richard

        1 Reply Last reply Reply Quote 0
        • MattFoxM
          MattFox
          last edited by MattFox

          @richard-mortimer said in maJsonStore (JSON store):

          <div style="border:2px solid blue;" ng-repeat="site in sites.sites">
          <ma-point-query query="'eq(tags.SiteName,SPS001)&eq(tags.Display,Customer Load)'" points="points" ></ma-point-query>
          <!-- show me everything -->
          <div style="color: white;background-color:black; border: 1px solid red;">--{{ site.name }}--<pre>{{ points }}</pre>--</div>
          </div>

          Yikes, you're repeating your queries multiple times and calling the same data. We may need to start moving you into angularJS component territory.
          However, if you're after that site name, you need to do this:

          <ma-json-store xid="sitesDataXID" value="sites"></ma-json-store>
          <div style="border:2px solid blue;" ng-repeat="site in sites.sites">
              <ma-point-query query="'eq(tags.SiteName,'+site.name+')&eq(tags.Display,Customer Load)'" points="points[site.name]" ></ma-point-query>
              <!-- show me everything in this point! -->
              <div style="color: white;background-color:black; border: 1px solid red;">--{{ site.name }}--<pre>{{ points[site.name] }}</pre>--</div>
          </div>
          

          if you have points="points" being used every time for each of your ma-point-query items, they'll continue to be updated and overwrite one another as they all share the same scope.
          Storing them in an object using the site name as the key makes it a bit easier.
          or alternatively!

          <ma-json-store xid="sitesDataXID" value="sites"></ma-json-store>
          <div style="border:2px solid blue;" ng-repeat="(index,site) in sites.sites">
              <ma-point-query query="'eq(tags.SiteName,'+site.name+')&eq(tags.Display,Customer Load)'" points="points[index]" ></ma-point-query>
              <!-- show me everything in this point! -->
              <div style="color: white;background-color:black; border: 1px solid red;">--{{ site.name }}--<pre>{{ points[index] }}</pre>--</div>
          </div>
          

          This will map everything by the index in your JSON store.
          Let me know how you go.

          Fox

          Do not follow where the path may lead; go instead where there is no path.
          And leave a trail - Muriel Strode

          1 Reply Last reply Reply Quote 0
          • CraigWebC
            CraigWeb
            last edited by

            I agree with Mattfox and I think Richard will be more familiar since you can code pure javascript functions in the component controller to manipulate your data. instead of pseudo angular/javascript

            I believe you are safe to use points="points" unless points is initiated somewhere else in the ng-repeats parent scope. As ng-repeat creates a scope for each iteration but will first look in the parent scope for points

            1 Reply Last reply Reply Quote 0
            • richard.mortimerR
              richard.mortimer
              last edited by richard.mortimer

              Sorry to drag up an old subject, but I've got a curious thing happening within my repeats - and I'm not sure if it's an Angular issue, or I've done something to upset it ...

              My code used two ng-if statements to determine if the value is output value is in watts or kilowatts, thus:

              <span ng-repeat="point in points[site.name]"><!-- Load -->
                  <ma-get-point-value point-xid="{{ point.xid }}" point="output"></ma-get-point-value>
                  <div ng-if="output.value > 1000">{{ (output.value / 1000) | number:1 }}kW</div>
                  <div ng-if="output.value <= 1000">{{ output.value | number:0 }}W</div>
              </span><!-- end Load -->
              

              The problem is - I'm sometimes getting two values returned, (for example 984W and 1kW) - if I directyly print the value on the screen via {{ output.value }} I'm seeing what I would expect to see (mostly integers, a couple of float types for some points).

              Am I doing something wrong here, or is there a better way to do this?

              [edit] Here's one I managed to catch as it happened:0_1559714978372_output_error.jpg

              Thanks

              Richard

              CraigWebC 1 Reply Last reply Reply Quote 0
              • MattFoxM
                MattFox
                last edited by MattFox

                Evening Richard!

                Are your points numeric types or alphanumeric?

                I say keep it simple and just do

                <span ng-repeat="point in points[site.name]"><!-- Load -->
                    <ma-get-point-value point-xid="{{ point.xid }}" point="output"></ma-get-point-value>
                    <div ng-if="parseInt(output.value) > 1000">{{  parseFloat(output.value / 1000).toFixed(1) }}kW</div>
                    <div ng-if="parseInt(output.value) <= 1000">{{ Number(output.value)}}W</div>
                </span><!-- end Load -->
                

                You don't have to use what I put int the div inner HTML. But as far as the ng-if is concerned at least you'd have a consistent read with your values.

                Do not follow where the path may lead; go instead where there is no path.
                And leave a trail - Muriel Strode

                richard.mortimerR 1 Reply Last reply Reply Quote 0
                • richard.mortimerR
                  richard.mortimer @MattFox
                  last edited by richard.mortimer

                  @mattfox said in maJsonStore (JSON store):

                  Evening Richard!

                  Are your points numeric types or alphanumeric?

                  I say keep it simple and just do

                  <span ng-repeat="point in points[site.name]"><!-- Load -->
                      <ma-get-point-value point-xid="{{ point.xid }}" point="output"></ma-get-point-value>
                      <div ng-if="parseInt(output.value) > 1000">{{  parseFloat(output.value / 1000).toFixed(1) }}kW</div>
                      <div ng-if="parseInt(output.value) <= 1000">{{ Number(output.value)}}W</div>
                  </span><!-- end Load -->
                  

                  I believed they were simply numeric - but whern I add the parseInt(output.value) everything disappears (as in - neither ng-if statement is true), similarly the same with the Number and parseFloat functions ...

                  If I do: <script>console.log(typeof {{output.value}});</script> I get:
                  0_1559716204069_syntax_error1.jpg

                  Cheers

                  Richard

                  1 Reply Last reply Reply Quote 0
                  • MattFoxM
                    MattFox
                    last edited by MattFox

                    I'll just have a quick look in the mango dash to see fi I can run some tests.
                    As for typeof you want: note javascript generally has a numeric. doesn't have ints or floats like compiled languages.

                    {{ typeof output.value }} //although i'm not confident if it will work...
                    

                    Do not follow where the path may lead; go instead where there is no path.
                    And leave a trail - Muriel Strode

                    richard.mortimerR 1 Reply Last reply Reply Quote 0
                    • richard.mortimerR
                      richard.mortimer @MattFox
                      last edited by

                      @mattfox said in maJsonStore (JSON store):

                      {{ typeof output.value }} //although i'm not confident if it will work...
                      

                      Nope, that didn't work ... :(

                      1 Reply Last reply Reply Quote 0
                      • MattFoxM
                        MattFox
                        last edited by MattFox

                        Ok, I can't replicate it. Let's go back to how you had it.
                        But make it this for your ng-ifs

                        <span ng-repeat="point in points[site.name]"><!-- Load -->
                            <ma-get-point-value point-xid="{{ point.xid }}" point="output"></ma-get-point-value>
                        <div ng-if="output.value > 1000">{{ (output.value / 1000) | number:1 }}kW</div>
                            <div ng-if="output.value < 1001">{{ output.value | number:0 }}W</div></span><!-- end Load -->
                        

                        Just humour me please.

                        EDIT: Could you also please give me a copy of the {{output}} for the problem one?

                        Do not follow where the path may lead; go instead where there is no path.
                        And leave a trail - Muriel Strode

                        1 Reply Last reply Reply Quote 0
                        • richard.mortimerR
                          richard.mortimer
                          last edited by

                          {{output}} is:

                          {
                             "id":2986,
                             "xid":"S2.DP_HOD-002_827990",
                             "name":"Customer Load - Active Power",
                             "enabled":true,
                             "deviceName":"H02 - B-30",
                             "readPermission":"RO, user",
                             "setPermission":"",
                             "pointFolderId":387,
                             "purgeOverride":false,
                             "unit":"W",
                             "useIntegralUnit":false,
                             "useRenderedUnit":false,
                             "pointLocator":{
                                "dataType":"NUMERIC",
                                "settable":false,
                                "modelType":"PL.PERSISTENT",
                                "relinquishable":false
                             },
                             "chartColour":"black",
                             "plotType":"SPLINE",
                             "loggingProperties":{
                                "loggingType":"ALL",
                                "tolerance":0,
                                "discardExtremeValues":false,
                                "overrideIntervalLoggingSamples":false,
                                "cacheSize":1
                             },
                             "textRenderer":{
                                "useUnitAsSuffix":true,
                                "unit":"W",
                                "renderedUnit":"W",
                                "format":"####.##",
                                "suffix":"",
                                "type":"textRendererAnalog"
                             },
                             "chartRenderer":{
                                "timePeriod":{
                                   "periods":1,
                                   "type":"DAYS"
                                },
                                "type":"chartRendererImage"
                             },
                             "rollup":"NONE",
                             "simplifyType":"NONE",
                             "simplifyTolerance":10,
                             "simplifyTarget":5000,
                             "templateXid":null,
                             "dataSourceId":116,
                             "dataSourceXid":"DS_Central_T_E01",
                             "dataSourceName":"Central-T-E01",
                             "dataSourceTypeName":"PERSISTENT",
                             "tags":{
                                "SiteName":"S002",
                                "Display":"Customer Load"
                             },
                             "lastPayload":{
                                "xid":"SPS002.DP_HOD-002_827990",
                                "event":"UPDATE",
                                "value":{
                                   "dataType":"NUMERIC",
                                   "value":118,
                                   "timestamp":1559717556655,
                                   "annotation":null
                                },
                                "renderedValue":"118 W",
                                "convertedValue":118,
                                "enabled":true,
                                "attributes":{
                                   "UNRELIABLE":false
                                }
                             },
                             "value":118,
                             "time":1559717556655,
                             "convertedValue":118,
                             "renderedValue":"118 W",
                             "unreliable":false
                          }
                          

                          Thanks

                          Richard

                          1 Reply Last reply Reply Quote 0
                          • MattFoxM
                            MattFox
                            last edited by

                            Sorry Richard, I'm not seeing anything sticking out here. The only thoughts I have is echoing out {{output}} inbetween both of the ng-if divs. Seeing how you're having two appear in one area makes me wonder if there's some sort of overlap or something stupid. Your values are definitely numeric.
                            The next best idea Ive got is checking your console after doing a page load to see if any angular errors crop up..
                            Otherwise I'm gonna have to call on Jared or Phil to help here. Sorry I cannot be of any further assistance. Either that or I'm just simply half asleep and it's staring me in the face!

                            Fox

                            Do not follow where the path may lead; go instead where there is no path.
                            And leave a trail - Muriel Strode

                            richard.mortimerR 1 Reply Last reply Reply Quote 0
                            • richard.mortimerR
                              richard.mortimer @MattFox
                              last edited by

                              @mattfox said in maJsonStore (JSON store):

                              Sorry Richard, I'm not seeing anything sticking out here.

                              Fox

                              That's cool - I'm kinda glad it wasn't something glaringly obvious, and I appreciate your help!!

                              Getting a couple of errors, but I'm not sure they are related:

                              0_1559720264023_console_output.jpg

                              Cheers

                              Richard

                              1 Reply Last reply Reply Quote 0
                              • CraigWebC
                                CraigWeb @richard.mortimer
                                last edited by CraigWeb

                                @richard-mortimer Hi

                                I don't think you need to user parseInt etc as javascript will evaluate it as a number when there is a comparator.

                                I tested this out with this code and got the desirable outcome

                                <div class="ma-designer-root" id="ad15c8a3-1798-45ab-9771-535bb550b828" style="width: 1366px; height: 768px; position: relative;" ng-init="points=[
                                    {xid:'DP_3414e074-39ae-4179-b3e7-0775e7cabc54'},
                                    {xid:'DP_a7485f76-5c52-4c42-b49a-f17b3276a2f8'}]">
                                    
                                    
                                <span ng-repeat="point in points">
                                    
                                    <ma-get-point-value point-xid="{{ point.xid }}" point="output"></ma-get-point-value>
                                    <div ng-if="output.value > 999">{{ (output.value / 1000) }}kW</div>
                                    <div ng-if="output.value < 1000">{{ (output.value)}}W</div>
                                </div>
                                

                                If you look at your screen shot where the 'error" happens , 1.4kW is from the previous ng-repeat itteration.
                                We can't see the rest of your code but by the looks of it, you have a table with nested repeats. I think you should refactor your code using ng-repeat-start and ng-repeat-end for all you nested repeats just to make sure the browser does not get confused.

                                Edit:
                                Another way to skin this cat would be to use a ternary expression.

                                <div class="ma-designer-root" id="ad15c8a3-1798-45ab-9771-535bb550b828" style="width: 1366px; height: 768px; position: relative;" ng-init="points=[
                                    {xid:'DP_3414e074-39ae-4179-b3e7-0775e7cabc54'},
                                    {xid:'DP_a7485f76-5c52-4c42-b49a-f17b3276a2f8'}]">
                                    
                                    
                                <span ng-repeat="point in points">
                                    <ma-get-point-value point-xid="{{ point.xid }}" point="output"></ma-get-point-value>
                                    <div>{{output.value >1000? output.value/1000:output.value}}{{output.value >1000?'kW':'W'}}</div>
                                </div>
                                
                                richard.mortimerR 1 Reply Last reply Reply Quote 0
                                • Jared WiltshireJ
                                  Jared Wiltshire
                                  last edited by

                                  @richard-mortimer I'm taking a guess at what is happening, but I'm pretty confident that this will fix it -

                                  <span ng-repeat="point in points[site.name] track by point.xid"><!-- Load -->
                                      <ma-get-point-value point="point"></ma-get-point-value>
                                      <div ng-if="point.value > 1000">{{ (point.value / 1000) | number:1 }}kW</div>
                                      <div ng-if="point.value <= 1000">{{ point.value | number:0 }}W</div>
                                  </span><!-- end Load -->
                                  

                                  Two things -

                                  • Use track by in your ng-repeat expression so that Angular can correlate which points correspond to each span element when the points change.
                                  • Just pass the point to the <ma-get-point-value> component instead of retrieving it by XID again

                                  Developer at Radix IoT

                                  richard.mortimerR 1 Reply Last reply Reply Quote 1
                                  • richard.mortimerR
                                    richard.mortimer @Jared Wiltshire
                                    last edited by

                                    @jared-wiltshire said in maJsonStore (JSON store):

                                    Two things -

                                    • Use track by in your ng-repeat expression so that Angular can correlate which points correspond to each span element when the points change.
                                    • Just pass the point to the <ma-get-point-value> component instead of retrieving it by XID again

                                    Thanks for that - I've made the changes and will keep an eye on it; unfortunately it only seems to happen at random times which makes it one of those "fun" bugs to iron out ... but I'm pretty confident that if you're pretty confident, it will probably be the right solution! :)

                                    Cheers!!

                                    Richard

                                    1 Reply Last reply Reply Quote 0
                                    • richard.mortimerR
                                      richard.mortimer @CraigWeb
                                      last edited by

                                      @craigweb said in maJsonStore (JSON store):

                                      <span ng-repeat="point in points">
                                          <ma-get-point-value point-xid="{{ point.xid }}" point="output"></ma-get-point-value>
                                          <div>{{output.value >1000? output.value/1000:output.value}}{{output.value >1000?'kW':'W'}}</div>
                                      </div>
                                      

                                      Sorry, I missed this reply - you are correct it's inside a larger loop, which iterates through each device - I'm going to try the ternary operator and see how that goes ...

                                      Any idea how to put the number filter in there? The kW was to one decimal place, and the W was to 0 ...

                                      Cheers

                                      Richard

                                      MattFoxM Jared WiltshireJ 2 Replies Last reply Reply Quote 0
                                      • MattFoxM
                                        MattFox @richard.mortimer
                                        last edited by

                                        @richard-mortimer I believe when you did | number:1 and | number:0 was more than sufficient. alternatively just use point.value.toFixed(1) and point.value.toFixed() repectively

                                        Do not follow where the path may lead; go instead where there is no path.
                                        And leave a trail - Muriel Strode

                                        richard.mortimerR 1 Reply Last reply Reply Quote 0
                                        • Jared WiltshireJ
                                          Jared Wiltshire @richard.mortimer
                                          last edited by

                                          @richard-mortimer said in maJsonStore (JSON store):

                                          Any idea how to put the number filter in there? The kW was to one decimal place, and the W was to 0 ...

                                          You would need another ternary operator. IMO the way you had it in the first place is easier to read.

                                          If you use this pattern often, consider adding an AngularJS filter to a user module. You could then use it just like
                                          <span ng-bind="point.value | formatPower"></span>

                                          Developer at Radix IoT

                                          1 Reply Last reply Reply Quote 0
                                          • richard.mortimerR
                                            richard.mortimer @MattFox
                                            last edited by

                                            @mattfox said in maJsonStore (JSON store):

                                            @richard-mortimer I believe when you did | number:1 and | number:0 was more than sufficient. alternatively just use point.value.toFixed(1) and point.value.toFixed() repectively

                                            Thanks - the colon in the | number:1 was interfering with the ternary operator and getting it confused; so, while I could pipe it through, I couldn't modify the final number based on which direction it took - the point.value.toFixed(1) did the correct thing for me ...

                                            Cheers

                                            Richard

                                            1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post