Adding a json Schema component to your Niagara station allows for the construction of an json payload to suit the requirements of your particular application.
There are examples in the palette which may help with learning how a Schema can be constructed. Simply drag the JsonExampleComponents and Schemas folder into a running station.
A schema is constructed by placing “entities” from the jsonToolkit palette below a JsonSchema in the station. Some entities may be simple - for example a json object
results simply in { }
characters, whilst others may yield the results of Niagara bql queries and therefore have potential to be more complex.
Once the schema construction is complete, the generate action is invoked either manually or automatically to update the output slot based on the current values retrieved from Niagara.
The String output
slot can be linked to onward points (or where necessary an Engine Cycle Message Queue), determining the transport protocol used to send the schema payload, for example MQTT or HTTP.
Note: the formatting shown in the Output dialog (with newlines and whitespace) is purely for presentation, the String output itself is minified and does not contain extraneous characters.
The schema supports a nested structure of child entities. These can be Objects, Arrays or Properties of various types. They may be populated with alarm, history or device or point data from Niagara.
Entity Type | Output |
---|---|
Object | “objectName” : { “name” : value, “name2” : value2…. } |
Array | “arrayName” : [ value, value2…. ] |
Property | “key”: value |
Property List | “key”: value, “key2”: value2 |
All entities (minus property) support having nested child entities. This allows a schema to be built using a tree structure with entities found in the jsonToolkit palette.
Every schema must have a root member that is allowed by the json standard, that means an object { }
or an array [ ]
.
Root objects/arrays will not have their name printed in the schema output, as they would when used beneath the root.
enabled - prevents generation of output, execution of queries and subscription to bound values, when false
generateJson - an action to request a rebuild and update of schema output. For relative schemas this causes the Base Query
to be evaluated and the results published.
forceGenerateJson - as per generateJson but forces the action regardless of current tuning settings.
clearCache - discards the last known values of bindings and cached query results.
clearOutput - sets the schema output to an empty string.
executeQueries - force an immediate execution of all the schemas queries.
Casing Rule | Output |
---|---|
Camel | camelCaseKey |
Pascal | PascalCaseKey |
Upper | UPPERCASEKEY |
Lower | lowercasekey |
Preserve | unchanged |
Spacing Rule | Output given ‘Space Temp’ |
---|---|
Remove | "SpaceTemp" : ... |
Keep | "Space Temp" : ... |
Add | Injects a space between caseChanges |
Hyphenate | "Space-Temp" : ... |
Underscore | "Space_Temp" : ... |
UrlEncode | "Space+Temp" : ... |
Date Format Pattern allows use of a Java SimpleDateFormat Pattern to define the time formatting used when a Niagara AbsTime is encountered in by Schema. e.g from a History Query, or the Current Time Property. ISO 8601 for example is yyyy-MM-dd HH:mm:ss.SSSZ
.
Numeric Precision is the number of decimal digits to show on exported floating point numbers, values will be rounded. Point facets are not used.
Use Escape Characters when false
any escape chars encountered will be unescaped - eg $20 will become a “ ” or space character.
Most Tuning Policies properties are explained by the driver documentation.
Update Strategy: determines when json string generation occurs:\ - On Demand - Update output when the generateJson action is invoked, this could be linked to a timer or other station logic.\ - COV - updates output when any binding target changes value, using subscription. Latest known values are cached and changes will cause the schema output to be updated.
There is an in built min write time
to ensure that hundreds of concurrent cov changes over a short time do not result in a deluge of json messages. For example with a setting of 5 seconds, if a change of value occurs within 5 seconds of the last, schema generation is deferred for 5 seconds. However if the max write time
has been exceeded then the schema generation is forced. Note the Force Generate Json
action overrides all these settings. Export Markers applied to numeric points also have a CoV Tolerance property which can be used to throttle output. The write on start
and write on enabled
properties are other ways to force schema generation.
This folder is where a Type Override component can be added to the schema, should it be necessary to override the default behaviour of how the schema writes converts specific datatypes to JSON. These apply to anywhere the datatype is encountered for an entire schema. Examples might be where Facets should be replaced to a locally understood value, eg ‘degC’ to ‘Celsius’, defining a different format for Simple types such as Color/RelTime, or perhaps to manage expectations for +/- INF in a target platform.
Refer to Type Override in the developer guide for further information.
Used to review the recent history of output from a json schema. Useful for occasions where the output updates rapidly such as generate json called in quick succession by a link, or a relative schema where the output is changed once per base item very quickly.
Either hit the Output History
button on a schema in workbench, or right click on the Schema History Debug slot and select ‘Spy Remote’.
The History Size allows you to store more but be careful not to fill memory with json strings. Reduce this value once you have finished debugging.
Exposes Schema generation, query execution and COV subscription metrics. These could be logged or linked to generate alarms if needed.
These are anticipated to help with sizing / provisioning capacity from a cloud platform by estimating the traffic a station is likely to generate with a given Json Schema. They may also assist in identifying performance problems, debugging can be assisted by using the reset action.
Queries | Generation | Subscription |
---|---|---|
queryFolderExecutions | requestSchemaGenerations | subscribes |
individualQueryExecutions | schemaGenerations | unsubscribes |
queryFails | schemaGenerationFails | subscriptionEvents |
lastQueryFailReason | lastSchemaGenerationFailReason | subscriptionEventsIgnored |
lastQueryExecutionMillis | outputChanges | cacheHits |
queryExecutionMillisTotal | lastOutputSize | cacheMisses |
queryExecutionMillisMax | outputSizeTotal | |
queryExecutionMillisAvg | outputSizeMax | |
outputSizeAvg | ||
resolveErrors |
Bound
Properties, Objects and Arrays are json entities which can use the current values of an Ord target to render their values. The Fixed
variants do not support binding.
When picking a bound object/array, you may choose which slots from the target to include in the resultant json container. Currently the options are:
Note that when choosing the bind target for a binding you could select any type of slot, from Devices to Control Points to out slots to simple values, there is no restriction.
Bound Arrays/Objects will output the value of each of the selected slots - see Slot Selection. The default behaviour for each encountered slot type is as follows:
Selection | Output |
---|---|
Strings | The string value unchanged |
Booleans | A json boolean |
Integer/Long | A json number |
Double/Float decimals | AQ json number rounded to use the schemas decimal places config |
Enum value | A json string that represent the enum value |
AbsTime | A string representation of the date foratted as per the schema config |
Control Point | A json string/number/boolean to represent the out slots value |
Status Value | A json string/number/boolean to represent the value |
Status | A json string to represent the value e.g {ok} |
Anything else | The string representation of the value as returned from the framework. This is often the type display name |
Note: bound objects/arrays do not recurse, only direct child slots are included.
Note: the above behavior has made a few assumptions about most expected case for example excluding the status string from certain types. All this behaviour may be overridden by program overrides.
For binding results you may choose what the key is in the key/value pair:
Selection | Output |
---|---|
Display Name | The Display Name of the Bound Property/Object/Array |
Target Name | The name of the ord target |
Target Display Name | The display name of the ord target |
Target Parent Name | The name of the ord targets parent |
Target Path | The absolute path of the target from the root of the component tree |
Hint: A Tag Property with
n:name
may be used to include point names.
Inserts a Json Object { }
(an empty named container for other schema entities)
BoundObject is a named json object whose child name/value pairs are the slots within that ord target.
Inserts a Json Array [ ]
(an empty named container for other schema entities)
BoundArray is a named json object which renders the values as a list.
Hard coded name value pairs which you always want to appear as constants in the json. You can also link in to these if the value is expected to vary. The current value will be included during the next generation event, triggered by CoV on a Bound entity or invocation of the generateJson action. A change in the value of any Fixed property will not trigger a CoV generation event in the way a Bound equivalent would.
Inserts the current value of the object specified in the binding.
BoundCSVProperty is a named json string which renders child slots as string comma separate list (no surrounding []
or {}
)
The ord is not bound like the other bindings, in that changes of value will not prompt Schema generation. The current value is retrieved from the station when the Schema is generated.
Allows a single tag value from the bound component to be inserted in the output.
If SearchParents is true then search up the hierarchy for the closest component with matching tag id (if tag not found on binding target)
A list of name/value properties based upon selected tags found upon a binding target.
A comma separated list specified in the Tag Id List Filter can limit the tags to be included in the output. Example: n:name
,n:type
or *
for all. If include namespace is true then the tag dictionary prefix is added to the key (eg hs:hvac).
Allows a single Facet value from a bound component to be inserted in the Schema output, for example the units of the current point.
Inserts a list of name/value facet properties based upon a comma separated list or * for all. Facet keys should be added as follows: units,mix,max
A named numeric value, which increments by 1 on each schema generation. Could be used for message Ids.
Inserts the Current Time a defined using the Schema Config Time Format property.
Inserts the Current Time in Unix Time, as seconds from the epoch.
Relative json schema enables scaling of json payload generation, and much faster engineering than seen so far.
The Schema discussed thus far used only absolute ords. In situations with many points this could limit scalability, one schema per point or device would not be an efficient way to proceed. In the same way that relative ords in graphics enable efficient engineering with the Niagara framework, the json Toolkit uses Relative Schema’s to provide a flexible way to output data:
The schema is fed base components via a Base Query
which are then resolved against the schema one at a time. In this manner it is possible to select, for example, all the Bacnet points in a station and then output their name, status and present value for export to the Cloud. If an engineer adds an extra device to the BACnet Network in future, then this can be “automatically” included in the data exposed by the station if the Base Query allows.
Alone, a Relative Schema can select data to export, or when combined with an Export Marker has the ability to send only recent history, or publish only when a set tolerance value is exceeded.
This base query would return all the overridden points beneath the Drivers container:
slot:/Drivers|bql:select * from control:ControlPoint where status.overridden = 'true'
This query returns all points with the Haystack Marker Tag hvac
slot:/|neql:n:point and hs:hvac
Note: The base query publish interval causes the base query to be re-executed periodically and triggers a complete publish output (of every returned component) at the interval selected.
Note: The
generateJson
action may also be invoked on the Schema to cause the base query to be (re-)evaluated.Warning: Be sure that the schema output itself is not included in the base query - this will quickly consume available Java heap memory!
For more information see How Schema Generation Works
Creates a file with the current output of the schema being viewed. To access use either the button on the workbench toolbar, or File > Export > Json Exporter.
This could be used with the Report Service to export on a regular basis, perhaps via file, email or ftp for a Machine Learning application or similar.
A URL like the following also allows access to the Schema output via the JsonExporter:
http://127.0.0.1/ord/station:%7Cslot:/JsonSchema%7Cview:jsonToolkit:JsonExporter