13 Replies Latest reply on Jan 3, 2014 4:05 PM by janh RSS
    janh Newbie

    Indirectly Referencing Thing Properties in Script

    I am looking for a way to iterate through a number of similarly named properties in an service to count the number of current alarms. I am not a JavaScript expert and have tried the following script but it does not seem to work:

    me.z_AlarmCount = 0
    for (var i=301;i<396;i++)
    var n = i.toString()
        me.DebugString = "me.Alarm_CCP_Boiler_" + n;
    {  
        if (("me.Alarm_CCP_Boiler_" + n) == 1)
        {
            me.z_AlarmCount = me.z_AlarmCount + 1;
        }
    }
       
    Any assistance or advise would be appreciated.

    Many Thanks

    Jan Hemper
    InVMA

      • Indirectly Referencing Thing Properties in Script
        adamr Creator

        Instead of "me.Alarm_CCP_Boiler_" + n

        Use me["Alarm_CCP_Boiler_" + n]

        • Indirectly Referencing Thing Properties in Script
          adamr Creator

          So full script would be...

           

          me.z_AlarmCount = 0for (var i=301;i<396;i++)var n = i.toString()    me.DebugString = "me.Alarm_CCP_Boiler_" + n;{       if ((me["Alarm_CCP_Boiler_" + n]) == 1)    {        me.z_AlarmCount = me.z_AlarmCount +1;    }}



          • Indirectly Referencing Thing Properties in Script
            adam Creator

            Hi Jan,

             

            If I understand you correctly, you want to count the number of occurrences for properties prefixed with Alarm_CCP_Boiler, which will give you the number of alarms. However, based on your for loop, it seems you're only interested in a subset of these alarms?


            If you simply want to count the number of occurrences for properties prefixed with Alarm_CCP_Boiler:

            <br>

            result = me.GetPropertyDefinitions(); // Get Properties for me


            var params = 

            {

              inclusive: true, // Include Matched Rows

              t: result, // Infotable to Filter

              pattern: "Alarm_CCP_Boiler" + "%", // Pattern to Match (% is wildcard)

              fieldName: "name" // Property Name Field Returned by GetPropertyDefinitions()

            };


            result = Resources["InfoTableFunctions"].LikeFilter(params); // Filter Properties

            me.z_AlarmCount = result.getRowCount(); // Count # of Alarms


            Will this work? Or are you interested in only a subset of these alarms?


            Thanks,

            Adam T



            • Indirectly Referencing Thing Properties in Script
              janh Newbie

              Many thanks guys, both of these comments are very useful and will help me to achieve exactly what I need. Just out of interest are the various functions available as server side resources documented anywhere, the Resources["InfoTableFunctions"].xxx seems extremely powerful (as I guess are the other resources) but I have just been looking and was struggling to find the documentation.

              Once again, many thanks

              JanH


               

               

              • Indirectly Referencing Thing Properties in Script
                adam Creator

                Hi Jan,

                 

                You can view documentation for Resources in the wiki – the relevant entry is entitled "5.07 Resources". For a quick view of all Resources (along with their code snippets) from +Composer, +check out the Snippets tab in the Script Editor.


                – Adam



                • Indirectly Referencing Thing Properties in Script
                  janh Newbie

                  Hi Adam,

                  Thanks for this, I have now managed to find the documentation for the resources. Could I ask one more question on this thread please. What I am actually trying to do is described below:

                  1. I have a number of parameters that are prefixed with Alarm_CCP_Boiler_, these parameters relate to alarms in a particular part of a plant.
                  2. Our client has asked us to display an active alarms table containing date of last change of the particular property, property name and property description for all properties with a current value of 1.

                  Could you give some advise on the recommended way to implement this type of functionality.

                  Once again, many thanks

                  Jan

                   



                    • Indirectly Referencing Thing Properties in Script
                      riaanl Explorer

                      Hey Jan,

                      I assume you just need to display the properties (with the date/description), and you do not need to perform automatic processing and storage of the property changing.  If this assumption is correct, then the following script should be a good starting point. 


                      If there is a need for historical storage of these alarms, then you could leverage the 'DataChange' event and write a subscription which stores the property values to either a stream or a datatable.


                      Here is the aforementioned script.  Please note, I used a custom dataShape called AlarmPropertiesDataShape which you would either have to create or change within the script.

                      ////////

                      // Create the result infotable from a custom datashape

                      // This datashape contains:

                      // - Name

                      // - Value

                      //  - Description

                      //  - Time

                      // CreateInfoTableFromDataShape(infoTableName:STRING("InfoTable"), dataShapeName:STRING):INFOTABLE(AlarmPropertiesDataShape)

                      var result = Resources["InfoTableFunctions"].CreateInfoTableFromDataShape({

                      infoTableName : "InfoTable",

                      dataShapeName : "AlarmPropertiesDataShape"

                      });


                      // Get the Property values with the time, value, and quality (VTQ)

                      // The VTQ results for each property is an infotable within each property column

                      // result: INFOTABLE dataShape: "undefined"

                      var propertiesVTQ = me.GetPropertyValuesVTQ();


                      // Loop through the infotable columns (the properties), and if it meets the criteria, add it to the result infotable.

                      var columnName = "";

                      var infotableColumns = Object.keys(propertiesVTQ.rows[0]);

                      for (var key in infotableColumns) {

                          columnName = String(infotableColumns[key]);


                          // propertiesVTQ (from GetPropertyValuesVTQ()) will always return a single row, so it is safe to reference that row using index 0.

                          // Since we have the column name, we can just use bracket notation to reference the specific column within that row  ==> propertiesVTQ.rows[0][columnName]

                          // Additionally, we know that the value for this column is an infotable, so its single row can be referenced using the rows object:  (propertiesVTQ.rows[0][columnName]).rows[0]

                          var vtqInfotableForProperty = (propertiesVTQ.rows[0][columnName]).rows[0];

                          

                          // Within this vtq row, you will have a value, time and a quality.

                          // if the value is one, add the new row to your result infotable

                          if (vtqInfotableForProperty.value == 1) {

                              var newRow = {};

                              newRow.Name = columnName;

                              newRow.Value = vtqInfotableForProperty.value;

                              newRow.Time = vtqInfotableForProperty.time;

                              

                              // Add the row to the infotable.

                              result.AddRow(newRow);

                          }

                      }


                      // Lastly, get the properties descriptions and perform an inner join on it against the result infotable.

                      // result: INFOTABLE dataShape: "PropertyDefinition"

                      var propertyDefinitions = me.GetPropertyDefinitions({

                       

                      type: undefined /* STRING /</div><div>});</div><div><br></div><div>// Use the Intersect function to perform an inner join</div><div>// result: INFOTABLE</div><div>var result = Resources["InfoTableFunctions"].Intersect({</div><div><span class="Apple-tab-span" style="white-space: pre;">     </span>t2: propertyDefinitions / INFOTABLE /,</div><div><span class="Apple-tab-span" style="white-space: pre;">     </span>t1: result / INFOTABLE /,</div><div><span class="Apple-tab-span" style="white-space: pre;">     </span>joinColumns2: "name" / STRING /,</div><div>    joinColumns1: "Name" / STRING -- note, this is case sensitive, and my datashape has "Name" defined, not 'name' /,</div><div><span class="Apple-tab-span" style="white-space: pre;">     </span>columns2: "description" / STRING /,</div><div><span class="Apple-tab-span" style="white-space: pre;">     </span>columns1: "Name,Value,Time" / STRING /,</div><div><span class="Apple-tab-span" style="white-space: pre;">     </span>joinType: "INNER" / STRING */

                      });

                      ////


                      Lastly, I can send an export of this script in a Thing if you want a working version.  Let me know.


                      Regards,

                      Riaan





                    • Indirectly Referencing Thing Properties in Script
                      janh Newbie

                      Thanks Riaan,

                      That was a great help, I think that I am starting to understand a little better now. I have added a further function to filter the result table before the inner join is performed and can display the required output in a grid. On the basis that the result table is dynamically created as the script runs, what is the best way to arrange the column order on a grid widget?

                      Regards

                      Jan

                       



                        • Indirectly Referencing Thing Properties in Script
                          paic Collaborator

                          If you click on the Grid widget then from the drop down or from the wheel towards the middle left, you can go to the Configure Grid Columns Menu.

                           

                          This menu then allows you to order and set visibility on the grid columns as well as their renderers.

                          • Indirectly Referencing Thing Properties in Script
                            riaanl Explorer

                             

                            Jan, 

                            I'm not sure I understand your question.  While the contents of the infotable is dynamically added, the columns are known, correct?  If so, just ensure that the service output has a datashape defined and you will be able to organize the column order within the mashup builder (as Pai just mentioned).


                            If you do not have the datashape defined in the service output, then you will not be able to manually order the columns in the mashup builder.  In other words, the mashup builder relies on the datashape definition for configuration.


                            Regards,

                            Riaan


                             



                          • Indirectly Referencing Thing Properties in Script
                            janh Newbie

                            Sorry guys, let me try and be a little more clear:

                            The service output has a datashape defined, when in the configuration environment I can configure the column order and size, any changes made are reflected on the mashup when viewed in configuration. When I actually view the mashup in the runtime environment all formatting is lost and the columns seem to revert to default / random formatting.

                            Sorry for the confusion.

                            Thanks

                            Jan

                             



                            • Indirectly Referencing Thing Properties in Script
                              janh Newbie

                              Hi guys,

                               

                              I did indeed have the 'ShowAllColumns' property checked, apologies for that.

                               

                              Many thanks for your help.

                               

                              Regards

                               

                              Jan