The views feature permits to add alternative names to identify addresses. Those names are dynamic (programmatic) and can be automatically updated when some specific addresses or gateways parameters change. The views are useful in the context of reading / writing addresses in the routes, in the logic module, or more rarely from external applications using the javascript API.
In the IoT universal gateway, there is 3 different ways to identify addresses:
#1
, #2
, #3
, ...myBacnetDevice¬%bac:local/analogValue:1
. The gateway name is separated from the address name by the ¬
symbol. If the universal gateway has only one gateway of a type (here BACnet), then the short format is sufficient and the gateway name does not need to be specified (e.g. %bac:local/analogValue:1
).The screenshot below shows examples of local bacnet addresses identified by id in blue, and by name in orange. An example of view is given in the next section.
This section introduces views with a practical example on the bacnet driver. As you can notice in Figure1, bacnet addresses name are technical and not very user friendly. The bacnet addresses naming scheme is described below.
%bac:
followed by the either %bac:local
for the local bacnet addresses of the Universal IoT gateway, or the physical address of an other bacnet device such as %bac:192.168.1.98
for BACnet IP or the mac id for bacnet MSTP such as %bac:3
for device with mac address number 3
.binaryInput
, binaryOutput
, binaryValue
, analogInput
, analogOutput
, analogValue
, multistateInput
, ... and so on) followed by :
and the bacnet object instance id (unique integer by object types) such as (1
, 2
, and so on).presentValue
, units
, description
, objectName
, and so on.This addressing scheme above contains all the information for the driver to build the bacnet packets and communicate with other bacnet devices. It is good from an automation point of view and does not break if a bacnet object name is modified, but it is not very user friendly. Generally technicians prefer to see and work with a bacnet structure following the three levels below.
presentValue
, units
, description
, objectName
, and so on.The bacnet driver includes by conception a native view called bacnetName, which permits to use the user friendly addressing scheme described above. The screenshot below shows how to display the list of the views from the web interface.
By defaults, views are not active. Each gateway can turn on and off its compatible views. Some views only applies to certain types of gateways, the alias view is available for all gateway types, but the bacnetName view is only available for bacnet gateways. In order to activate the bacnetName view on our demo bacnet named gateway myBacnetDevice, the gateway menu can be used as shown below.
Once the view is activated, it can be seen from the gateway. Here the bacnetName view ressembles to what bacnet explorers usually display.
The view can be used to explore the bacnet devices and their objects more easily, but it can also be used to create routes between objects. By drag & dropping myBacnetDevice/objName
onto myBacnetDevice/objName2
a route is created between the 2 view identifiers and the present value of myBacnetDevice/objName
is routed to the destination address myBacnetDevice/objName2
. When routing using views it is advised to first make sure that the view name will not be modified in the future.
A custom view is a javascript function transforming each address of one gateway to its new view name (string). Custom views can be created from the Views list by clicking the Insert view button.
A new view is created, it is named "newView", and on the right pannel it is possible to select the target driver / gateway type. Below the gateway driver of type "internal" is selected. The function here in the example replaces the first address name character ($
for internals) by the prefix %internal:
The following code snippets below show the native views implementation of the Alias view and the bacnetName view. This code can be used as a starting point for new views creation.
function alias (adr){
return adr.alias
}
function bacnetName (adr, getAddress){
var levels = adr.name.split("/")
var parsed = {
'device' : levels[0].substring("%bac:".length),
'type' : levels[1] && levels[1].split(":")[0],
'instance' : levels[1] && levels[1].split(":")[1],
'property' : levels[2]
}
var devAdrName = "%bac:"+parsed.device
var objAdrName = parsed.type ? devAdrName + "/" + parsed.type + ":" + parsed.instance : null
var ret = null;
if(objAdrName){
var devAdr = getAddress(devAdrName)
var propAdrName = parsed.property ? (objAdrName + "/" + parsed.property) : null
var objNameAdr = getAddress(objAdrName + "/objectName")
if(propAdrName){
ret = {
view : [devAdr && devAdr.value && devAdr.value.name,objNameAdr && objNameAdr.value, parsed.property],
events : ['newValue '+ (adr.gateway_id + "¬" + devAdrName),'newValue '+ (adr.gateway_id + "¬" + objAdrName + "/objectName")]
}
}else{
ret = {
view : [devAdr && devAdr.value && devAdr.value.name, objNameAdr && objNameAdr.value],
events : ['newValue '+ (adr.gateway_id + "¬" + devAdrName), 'newValue '+ (adr.gateway_id + "¬" + objAdrName + "/objectName")]
}
}
}else{
ret = {
view : [adr.value && adr.value.name],
events : ['newValue ' + adr.id]
}
}
if(ret.view.findIndex(e => !e) != -1){
ret.view = null;
return ret;
}
// Escape the normal slash character "/" by the special slash "∕".
ret.view = ret.view.map(e => e.replace(/\//g,"∕")).join("/")
return ret
}
View identifiers are different from unique identifiers such as the address id or address name in the sense that a single view identifier can refer to multiple addresses, and a single address can have multiple view identifiers. If we have the table below, writing a value to the view identifier A
effectively writes to two different addresses.
|
|
This fact can be used to group together addresses of the same nature and perform group actions on those. For example if you have a KNX bus with group addresses 1/2/3
, 1/2/4
, 1/2/5
managing lights, it is possible to use the alias view and map these addresses to the single view identifier KNX_LIGHTS
. If you do so, it becomes easy to turn on or off all the lights by writing a single 1 or 0 on the KNX_LIGHTS
group identifier.