This feature is restricted to users with specific access to the platform. Learn more about User Management.

Scripts can be categorized into two types: Headless, and Browser. Php is the programing language used to develop content for platform  This provides excellent scripting support within the platform, allowing the creation of both browser scripts and headless scripts in PHP. Python and SQL scripts, by contrast, are headless scripts only.

 

Headless Scripts

Headless scripts leverage the Script Scheduler.  See the Integrated Development Environment section for more details.

Add New Headless Script

  • On any Type or Instance open the Scripts tab and click the 'plus' icon at the top right. This opens the  Add Script dialog.
  • Provide a meaningful name/description in the Script/Description fields.
  • Use the Language dropdown to select the script language.
    • If you choose PHP, a new dropdown will display that asks for the Run Mode. PHP allows for the following:
      • Headless Script
      • Browser Script
      • Class Script
      • Display Script
    • Python and SQL scripts can only be headless scripts.
  • Select a Template. Each script type offers several starter scripts or a blank script. For the PHP examples below, select “Blank Script” as the Template.
  • Use Last Output: Scheduled scripts can store and use the last output from a script as input the next time the script is run. 
  • Click the Create button

Once the the Script is created it will show up in the Scripts Grid.  To add or edit code, click the icon in the IDE column.  Double click the row to invoke the Edit Script dialog.  To execute code in the IDE, click the Run button at the bottom right. 

Schedule a headless script:

You don't have to schedule a script when you create it - you can do so once it is working the way you want it to. By default, unless you set the schedule when you created the script, all scripts have Scheduled set to False, To schedule the script:

  • double-click the script row in the Script tab to open the "Edit Script" dialog or, from within the IDE, click the Edit link at the lower right to open “Edit Script” dialog.
  • In the “Scheduling” section, set Scheduled to True
  • Click the Change button next to Frequency.
    • Set the Frequency as needed. As you change the period, different options will be presented to hone the exact frequency required.
  • Click Update.
  • In the Script dialog, click the Run check box and then the Submit button.

Note

Reopening the IDE while a Script is scheduled will remove the Run button.  Clicking the View History button will render a history of context data.

Also, a good home for Scripts not associated with a Place or Equipment in the model is in a separate new Library specifically for Scripts. This can be useful for all scripts except those aiming to get or set an Attribute of the parent Instance using the node_id from the Context object.

 

The following Php script examples can be copied into and executed within the IDE of any ThinkIQ instance.

Context Counter

The intent of this Counter script is to show how to use custom Context.  This example requires the following JSON entry in the Custom field of the Script dialog:

  • {"counter": 0}

Code

<?php

//required for context object
require_once 'thinkiq_context.php';

//get context
$context = new Context();

//get the custom input "counter" defined in the JSON
//of the Custom field from the Add Script dialog
$counter = $context->custom_inputs->counter;

//increment counter
$counter++;

//create an associative array with the named key equal to the Custome field
$return_array = array('counter' => $counter);

//write the context data
$context->return_data($return_array);

 Output

{"counter":1,"start_timestamp":"2022-01-16T12:48:36.000+00:00","interval_seconds":60}

 Note

The value for counter in the above JSON output will increment on every execution (manual using the Run button or via Schedule).

Get Current Time

It is recommended PHP scripts use the RFC3339_EXTENDED format for the best compatibility with PostgreSQL and JavaScript.

Code

<?php

//create a DateTime using microtime and format using RFC3339_EXTENDED 
$current_time_with_millisecond = DateTime::createFromFormat('U.u', microtime(true))->format(DateTimeInterface::RFC3339_EXTENDED);

//output 
echo $current_time_with_millisecond;

Output

2022-01-16T13:33:11.519+00:00

Get Time String

This example gets a RFC3339_EXTENDED formatted time from a string.

Code

<?php

//create a DateTime from the string '2021-12-22 03:05:00.000' 
$time_from_string = DateTime::createFromFormat('Y-m-d H:i:s.v', '2021-12-22 03:05:00.000');

//format to RFC3339_EXTENDED
$time_from_string_formatted = $time_from_string->format(DateTimeInterface::RFC3339_EXTENDED);

//output
echo $time_from_string_formatted;

Output

2021-12-22T03:05:00.000+00:00

 

Browser Scripts

At this time, browser scripts can only be created with the Php language.

Add New Browser Script

Add a Browser Script using the “Blank Script” Template:

  • On any Type or Instance open the Scripts tab and click the 'plus' icon at the top right. This opens the  Add Script dialog.
  • Provide a meaningful name/description in the Script/Description fields.
  • Use the Language dropdown to select “php”.
  • For these examples select “Blank Script” as the Template.
  • Click the Create button

 

The following are examples of Php scripts with an "Output To" value of Browser.

Value Stream To JSON

A Value Stream is a ThinkIQ data structure intended for the handling and representation of timeseries data.  The following code retrieves a value stream via the PHP API and then ultimately outputs a JSON array. 

Code

<?php

//use model node from the PHP API
use \TiqUtilities\Model\Node;

//this is required for the Context object
require_once 'thinkiq_context.php';

//value stream object
class value_stream {
    public function __construct($value, $timestamp) 

    {
        $this->value = $value;        
        $this->timestamp = $timestamp;
    }
}

//get thinkiq context of parent from std inputs of the Context
$context = new Context();

//get Node object
$parent_instance = new Node($context->std_inputs->node_id);

//get attributes from $parent_instance
//required to populate the attributes propety of the Node object
$parent_instance->getAttributes();

//get the setpoint_publish Attribute object
$attribute = $parent_instance->attributes['setpoint_publish'];

//start and end times from string
$start = new Datetime('2022-01-16 00:00:00');
$end = new Datetime('2022-01-16 00:04:00');

//get value stream
$attribute_value_stream = $attribute->getTimeSeries($start, $end);

//need array to for the json_encode
$output = array();

//for each $setpoint_publish_value in the value stream
foreach($attribute_value_stream as $attribute_ts_value) {
    //create a new value_stream object passing in the 
    //timestamp and value into the constructor
    $vs_record = new value_stream($attribute_ts_value['value'], $attribute_ts_value['timestamp']);

    //push the new valuestream object into the output array
    array_push($output, $vs_record); 
}

//echo output to json
echo json_encode($output);

Output

[

{"value":"5","timestamp":"2022-01-16 00:00:00.000+00:00"},

{"value":"6","timestamp":"2022-01-16 00:01:00.000+00:00"},

{"value":"7","timestamp":"2022-01-16 00:02:00.000+00:00"},

{"value":"8","timestamp":"2022-01-16 00:03:00.000+00:00"},

{"value":"9","timestamp":"2022-01-16 00:04:00.000+00:00"}

]

 

 

Get Current Value

The intent of this script is to show how to get the current value of an Attribute from the fqn of the Attribute.  This example requires the following JSON entry in the Custom field of the Script dialog:

  • {"attribute_fqn": "services.services_parent_instance.nps.tank_skid.tank.level"}

Code

<?php
//use model of the PHP API
use \TiqUtilities\Model;

//this is required for the Context object
require_once 'thinkiq_context.php';

//used for fqn value pair objects
class fqn_value {
    public function __construct($fqn, $value) 
    {
        $this->fqn = $fqn;
        $this->value = $value;        
    }
}

//get Script Context Object
$context = new Context();

//get custom input attribute fqn
$attribute_fqn = $context->custom_inputs->attribute_fqn;

//new up an attribute from fqn
$attribute = new Model\Attribute($attribute_fqn);

//get values
$current_value_array = $attribute->getCurrentValue();

//get current value
$current_value = $current_value_array["value"];

//need array for the json_encode
$output = array();

//create new fqn_value class
$fqn_value = new fqn_value($attribute_fqn, $current_value);

//add to output
array_push($output, $fqn_value);    

//echo output as JSON
echo json_encode($output);

Output

[{"fqn":"services.services_parent_instance.nps.tank_skid.tank.level","value":"50"}]

Current Value to Browser

The above "Value Stream To JSON" and "Get Current Value" scripts output JSON.  This Script example illustrates how to get this JSON data into a browser page.  In addition, this code sample introduces the basic use of Vue.js used extensively in purpose built UI.

Code

<?php
    use Joomla\CMS\HTML\HTMLHelper;

    // sets up a reference to tiq.core.js
    HTMLHelper::_('script', 'media/com_thinkiq/js/dist/tiq.core.js', array('version' => 'auto', 'relative' => false)); 
?>

<!-- HTML starts here - we make a simple structure to display the results -->
<!-- id="app" is used by Vue.js -->
<div id="app">
  <ul>
     <!-- '{{ }}' used by Vue.js for data binding -->
    <li>FQN: {{fqn}}  </li>
    <li>Value: {{value}}  </li>
  </ul>
</div>
 
<script>
    //Vue.js variable 
    var app = new core.Vue({
        el: '#app', // associates Vue.js to div with the id="app"

        //Vue.js data
        data: {
            fqn: "",
            value: 0
        },

        //Vue.js methods
        methods:{

            // this function calls back to the server to fetch data
            requestData(attribute_fqn) {
                let this_vue = this; // gets a handle to the Vue.js object this

                // ajax call
                jQuery.ajax({
                    method: "POST",
                    url: "index.php?option=com_thinkiq&task=invokeScript",
                    data: {
                        attribute_fqn: attribute_fqn, // the full fqn of the attribute with the value of interest 
                        output_type: 1, // important keeps all execution inside the CMS

                        // full script file name; copied from Mini IDE of the get_current_value script
                        script_name: "get_current_value_18762688.php" 
                    },
                })

                // the data request succeeded, so parse the response and apply to Vue.js data
                .done(function (response) {
                    let parsed_response = JSON.parse(response);
                    let result = JSON.parse(parsed_response.data.stdout);
                    this_vue.fqn = result[0]['fqn'];
                    this_vue.value = result[0]['value'];
                })

                // the data request failed
                .fail(function (response) {
                    alert("Error.  See console log for details");
                    console.log(response);
                })
            }
        },

        //this is an initialization event for Vue.js
        mounted() {
            let this_vue = this; //gets a handle to the Vue.js object this

            // request data using the full fqn of the attribute with the value of interest
            this_vue.requestData("services.services_parent_instance.nps.tank_skid.tank.level"); 
        },
    })
</script> 

Output (browser page)

  • FQN: services.services_parent_instance.nps.tank_skid.tank.level
  • Value: 25