cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Indirectly Referencing Thing Properties in Script

Highlighted
Level 1

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

13 REPLIES 13

Indirectly Referencing Thing Properties in Script

Instead of "me.Alarm_CCP_Boiler_" + n

Use me["Alarm_CCP_Boiler_" + n]

Indirectly Referencing Thing Properties in Script

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

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

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

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

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

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

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

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.