The sqa-common
JS library is a collection of utilities to support the clients of the SQA api.
It is provided as a node module published on the public npm registry.
Add the following dependency to package.json
:
"@3e/sqa-common": "^1.1.0"
and import the module where relevant:
import sqa_common from '@3e/sqa-common';
Reference documentation for the utility functions provided by the sqa-common
library.
Example payload returned by the /views
endpoint:
[{
"category": "GENERAL",
"sqid": "view-sqid",
"ref": "app/views/view-sqid",
"name": "Plant level template view",
"type": "CHART",
"type_option": "TIME",
"owner_type": "SYNAPTIQ",
"label": "Plant level template view",
"id": 10001,
"parameters": [
{
"id": "Period",
"class": "Parameter",
"parameter": {
"class": "Period",
"label": "Period",
"initial": "last-12-months"
}
},
{
"id": "Granularity",
"class": "Parameter",
"parameter": {
"class": "Granularity",
"label": "Granularity",
"initial": "1-months"
}
},
{
"id": "plants",
"class": "Parameter",
"parameter": {
"class": "ObjectRef",
"label": "Plant",
"labelKey": "assetType.PLANT.label",
"constraint": {
"object_category": "plants",
"include_obsolete": false
}
}
}
]
},...]
In the following paragraph we will refer to the json payload in above as viewsPayload
.
Given the parameter
field from the payload returned by a call to /views
, viewVariablesRefCategories
returns
an array of view asset ref categories.
For example:
sqa_common.sqa.common.viewVariablesRefCategories(viewsPayload[0].parameters);
returns ["plants"]
.
IMPORTANT: this is very alpha and subject to change.
The sqa common library is able to create visualizations (specifically, highcharts) and populate them with data.
To get a simple chart working, use the following steps.
The library needs to be able to call the api so it can access /logical_devices
, /indicators
(to construct the highcharts spec) and /data
(to populate it)
Create an api functon that will call an endpoint on our api with authentication, and call the callback with the json response.
Then set the api fn using
sqa.common.setApiFn(apiFn)
This can be done (for example) by calling /views/<id>
from the api
This is necessary before the view can be rendered.
\\ to set the granularity (setView here is coming from the react hook)
sqa.common.setView(sqa_common.setGranularityParameter(view, "15-minutes"))
\\ to set the period
sqa.common.setView(sqa_common.setPeriodParameter(view, "last-month"))
\\ or, for a custom period
sqa.common.setView(sqa_common.setPeriodParameter(view,
{"start":1622498400,
"end":1624226400}}))
\\ to set an object parameter by id
sqa.common.setView(sqa_common.setObjectParameter(view, "plants", "plants/P0237"))
sqa.common.getVisualization.then((visualization) => {
sqa.common.populateVisualization(visualization, (visualization) => {
console.log(visualization);
})
})
let cancel = sqa.common.populateVisualization(visualization, (visualization) => {
console.log(visualization);
})
cancel()
The function sqa.common.newEmptyView(options)
will create a new view ready to add objects and indicators to.
The options available are currently as follows:
{
granularity: "15-minutes",
period: "last-24-hours",
view-type: "time-chart",
description: "description",
label: "label"
}
The first dropdown is the list of available levels. This list is static, and stored in the variable sqa.common.Levels
It has a format like:
[{
"value": "site",
"label": "Site"
},
{
"value": "ac-node",
"label": "AC Node"
}]
The list of available containers depends on the selected level, and can be retrieved using the function sqa.common.getContainers(value)
where value is the value of the selected level.
It has a format like:
[{
"value": "all-sites",
"label": "All Sites"
},
{
"value": "plants/P0397",
"label": "BE Brugge"
}]
Call /logical_devices?ld_type=&container=&envelope=true
Note: the logical devices is paged so to ensure you get all the objects, navigate through the pages using the after
cursor. Using limit=100000
is not guaranteed to work as we may place a maximum on the limit property.
The endpoint indicators?level=<selectedLevel>&locale=<locale>
will return the full indicator information with label, unit, key etc. This can be cached.
The endpoint ld_indicators?object=<selectedObject>&object=<anotherSelectedObject>
will return the indicator keys that can be applied to the selected objects. This can be then combined with the full indicator information from /indicators
to provide the label and key for the applicable indidators.
The function sqa.common.addEnumDataset(view, objects, indicators, options}
will return a new view with the dataset added.
Objects: is a list of object refs e.g. ["plants/P0237","plants/P0350"]
Indicators: is a list of indicator keys e.g. ["irradiance"]
Following the designs, this should be called once per indicator so that the graphical representation and options for each indicator can be independently modified.
Use the function sqa.common.getTemplates(<view>, <spec>)
where spec
is an object like:
{
selectedLevel:"ac-nodes",
selectedContainer:"plants/P0237"
}
The function needs to call the api to get the labels for logical devices, so will return a promise. The promise will resolve to a list of templates like so:
[{:value "select-one",
:label "Selectable site"}
{:value "select-all",
:label "All sites"}]
With the templates, you only need to call `/indicators?level=&locale=
The function sqa.common.addTemplateDataset(view, spec, indicators, options}
will return a new view with the dataset added.
Spec: is an object like:
{
selectedLevel:"site",
selectedTemplate:"select-one",
selectedContainer: "site_groups/GRdemo.7"
}
Indicators: is a list of indicator keys e.g. ["irradiance"]
Following the designs, this should be called once per indicator so that the graphical representation and options for each indicator can be independently modified.
The function sqa.common.getDatasets(<view>)
will return the datasets available for the view. It needs to call the api to resolve the indicators and logical devices so will return a promise, which resolves to an array with one entry per dataset, like the following:
[{id:"bb380abd-ea20-4239-b3dc-077cd3308c77",
indicators:
[{level: "sites",
label: "Irradiance",
unit: "W/m2",
unit_key: "W_M2",
description: "Irradiance in the plane of the array(s) calculated using the same configuration and data as <i>Irradiation</i>.",
key: "irradiance"}],
objectSetLabel: "All sites",
objectSet: {template: "select-all", level: "site"},
representation: "line"}]
For enum datasets, the object set will also contain the resolved objects, which can be used to populate the expanded view, and the additional counter label.
[{id:"bb380abd-ea20-4239-b3dc-077cd3308c77",
indicators:
[{level: "sites",
label: "Irradiance",
unit: "W/m2",
unit_key: "W_M2",
description: "Irradiance in the plane of the array(s) calculated using the same configuration and data as <i>Irradiation</i>.",
key: "irradiance"}],
objectSetLabel: "BE Brugge",
objectSet: {
template: "enum",
level: "site",
objects: [{
name: "BE Brugge",
level: "site",
ref: "sites/P0237",
type: "value"
}]
},
representation: "line"}]
The basket will return an id for each dataset, which can be used as a handle to remove or modify it.
To remove:
sqa.common.removeDataset(<view>,<id>)
To update:
sqa.common.setDatasetOptions(<view>,<id>,<options>)
Currently the only available option is:
{
graphicalRepresentation:"line"
}
The list of representations is available from sqa.common.Representations
The variable sqa.common.ViewTypes
lists the available view types, currently as follows:
- Time chart
- Object heatmap
- Scatter chart
- Time table
- Object table
- Object chart
You can use the display
key in the visualization spec to determine whether to show a highcharts view or a data table.
The tables (object table and time table) return a spec as follows:
{
display:"table",
header: ["Object" "Irradiance" "Power AC"],
rows: [["BE Brugge" 100 200],
["BE Ghent" 300 400]
}
Some views will only work in certain cases.
The object heatmap requires exactly one indicator The scatter chart requires exactly two indicators, and the same object set for each indicator.
If the requirements are not met, getting the visualization will return a message spec:
{
display:"message",
value: "scatter-chart-object-sets-unmatched",
label: "Object sets must match for each indicator in a scatter chart"
}