The module contains several components for the processing of incoming json messages. These fall into 3 categories of tool:
Each of these types have an independent enabled
property for disabling, and a route
action to which you should link the incoming JSON string payload. Each type also includes a lastInput
and lastResult
property for debugging, and a runLastInput
action for testing changes.
Message Router components are used to redirect an incoming message (or subset) to a new slot so that links may redirect the JSON to be handled by another component.
The Json Message Router allows inbound messages to be transferred to an onward component suitable for processing, or handling, the message.
By adding dynamic slots of type baja:String with a name matching the value of the key slot, the entire incoming message will be routed to that slot for onward processing. Slots are added using the slot sheet view.
Dynamic String slots can be added using the addSlot
action on the router, with learn mode, or manually using the slot sheet view. They should use transient and read-only flags to avoid onward handlers running again at station start.
The message below would be routed to a String slot named “alarmAck” if the key is set to “messageType”.
{
"messageType": "alarmAck",
"user": "Maya",
"alarms": [ "5cf9c8b2-1542-42ba-a1fd-5f753c777bc0" ]
}
Unlike the Json Message Router which forwards the whole json payload to added slots intact, the Json Demux Handler passes a selected part of the message into the slots added. The slots added must match the key name, to select that key, and should be either Boolean, Numeric or String to match the json value.
Take this example payload:
{
"hue":43211,
"sat":254,
"bri":254,
"on":true
}
Once a slot of type baja:Double
named "hue"
is added to the demux handler, and the payload passed to the route
action - the hue property will expose 43211
for use in the station.
| |
|
Nested JSON objects can be extracted by adding a String with appropriate name, eg a demuxed String named ‘data’ would contain the entire nested object below:
{
"type" : "line",
"data" :
{
"labels" : ["Sunday", "Monday"],
"values" : [ 1, 2 ]
}
}
The demux router is a very basic method of selecting data of interest, and likely will become inefficient to use when faced with a large payload and chained routers. An approach with far more features is Json Path, described below.
Selectors are components which take an inbound Json message, apply some selection criteria and set the result in an out slot. This might be a subset of the JSON or it could be e.g the size of a message or the result of an aggregate function such as the sum of a repeated value.
Allows selection of value inside JSON array by index
Returns a boolean if the specified key is present in the payload
Returns the index of a given key within a JSON object
This selector will sum all values found in the payload matching the key (numeric values parsed only)
Returns all values found matching the key inside an array
Returns the length of the first object or array that matches the key
The JsonPath
component allows data to be interactively located and extracted from JSON structures using a special notation to represent the payload structure.
For the example below, the first item in the values array (1) can be selected using a Json Path of $.data.values.[0]
:
{
"type" : "line",
"data" :
{
"labels" : ["Sunday", "Monday"],
"values" : [ 1, 2 ]
}
}
In this example a single numeric value was selected, however it is possible to select a subset of the incoming Json for example: $.data
would select the entire data object into the out slot, or $.data.values
would select the entire Json array. Any expression containing a search with ..
for example $..labels
will return search results enclosed within an outer array.
Much more explanation of this powerful tool can be found online:
The remaining sections describe JSON message handlers which are components designed to perform a specific task with the data routed/selected via the other inbound components.
If alarms are exported from the station and include the UUID, then that unique id can be passed back via a Alarm Uuid Ack Handler.
The expected format is shown below, where the array allows multiple alarms to be acknowledged at once.
{
"user": "Maya",
"alarms": [ "5cf9c8b2-1542-42ba-a1fd-5f753c777bc0" ]
}
The user value is stored on the alarm record, to identify which user ack’d the alarm in the remote application. If the user key is omitted the component will still try to ack the alarms but using the fallback name “AlarmUuidAckUser”.
Note: the Json Schema Service runAsUser is a prerequisite for this handler to work. The specified user must have admin write permissions for the alarm class of the records being acked.
AckSource is a String appended to every AlarmRecord acknowledged, to allow auditing in future. It is stored as AckSource in the alarm data.
AckResult, this topic report the results of alarm ack to allow logging or post process activity. Example Output:
"Ack-ed alarm " + record
"Already ack-ed in alarmDb " + record
"Could not create BUuid from " + uuid
The SetPointHandler
sets incoming setpoint values to control writable ControlPoints.
{
"%idKey%" : "x",
"%valueKey%" : y,
("%slotNameKey%" : "slotName")
}
The Control Points are located by handle ord in the form: "%idKey%" : "323e"
Note: A
runAsUser
is mandatory for use of the Setpoint Handler. See the The Json Schema Service.Not currently supported: override/duration or status parameter. Nested keys.
Like the Setpoint Handler, however Export Setpoint Handler allows an external json message to change the value of a Control Point identified by the id property of an Export Marker.
Locating target points like this can be used to support a station where the points are “registered” by way of a unique key from the “cloud” platform. Once the cloud platform has returned a suitable identifier for an Export Marked point, then this setpoint handler can be used to apply write messages from the platform using that id, rather than the Niagara slot or handle ord (for example).
The JsonExportRegistrationRouter and JsonExportDeregistrationRouter are used to allow the behaviour described above, applying a unique identifier from an external system onto an Export Marker
This allows the cloud (or other “external system”) target to assign it’s own identifier or primary key to export marked points in the Niagara station which can be used to locate them in future, or included in exports to that cloud system.
The messages should be in the format
{
"messageType" : "registerId"
"niagaraId" : "h:a032",
"platformId" : "mooseForce123"
}
or
{
"messageType" : "deregisterId"
"platformId" : "mooseForce123",
}
Note: the messageType is not used by this class, that would be used simply to route it to this handler and so can be changed as needed.
Loosely demonstrates some of the routers / selectors based upon a fictional point search json message.
Copyright 2019 Tridium, Inc. All Rights Reserved.