The OpenGate API provides a solution for the management and organisation of Internet of Things (IoT) devices and assets. At the core of this organisational structure are the channels, which are a vital component of an efficient device and asset management system, enabling streamlined operations and enhanced oversight.
Understanding OpenGate Channels
The Channels feature of the OpenGate group unifies the categorisation of devices and assets, thereby simplifying the management of complex systems and providing a powerful tool for the application of policies, the execution of commands and the analysis of data across a fleet of devices. The use of Channels allows for the straightforward management and interaction with devices that share common characteristics or are part of a specific project or geographic location.
Key Benefits of Using Channels
Simplified Management: Organise devices and assets into manageable groups.
Targeted Operations: Execute commands and policies on a specific group of devices efficiently.
Enhanced Analytics: Analysing data at the group level allows you to gain insights that may otherwise be overlooked when looking at the data individually.
Importance of User and Work Group Assignments
In order to gain access to and assume control of channels, it is necessary for the user account associated with OpenGate to be incorporated into a workgroup. This method of access control, which is based on a multi-layered structure, guarantees that only those individuals who have been duly authorised will be able to interact with the devices and assets within a given channel. This approach ensures that the environment is secure and under the control of the relevant authorities.
How to Assign Work Groups to Channels
Access the OpenGate User Management interface.
Select the workgroup to be assigned to a Channel.
Specify the Channels to which the workgroup is to be granted access.
Save the changes to implement the new access permissions.
By meticulously assigning work groups to channels, it is possible to maintain a high level of security and ensure that users only have access to the devices and assets that are relevant to their role or of interest to them.
In the context of the Internet of Things (IoT), an entity represents any monitoring element.
OpenGate offers four types of entities: asset, device, subscription, and subscriber. The resourceType field is used to set the entity type. The following table illustrates the process for setting each entity type:
Entity
ResourceType attribute
Description
Provision
Asset
entity.asset
The software enables users to create new entities that are distinct from the device environment.
OpenGate supports a variety of entities, each of which is identified by a unique identifier.
Administrative data attributes
id: Each Internet of Things (IoT) entity on the platform is assigned a unique identifier automatically by the platform.
provision.device.identifier: The customer-generated ID is a string that identifies a device in a specific organisation. HTTP/1.1 201 Created Location: http://api.opengate.es/north/v80/provision/organizations/{organizationName}/devices/device_1 It is imperative that you use this identifier as a URL suffix when you wish to retrieve, update or delete your device.
provision.device.communicationModules[].identifier: The customer-generated ID is a string that identifies a communication module.
provision.device.communicationModules[].subscription.identifier: It is a customer-generated identifier comprising a string that identifies a subscription.
provision.device.communicationModules[].subscriber.identifier: It is a customer-generated identifier comprising a string that identifies a subscriber.
Administration object attributes
It is a requirement for all OpenGate entities to operate within an administrative context.
Attributes
organization: the organization that owns the entity.
Forbidden in entity update operation
Required in entity insert operation
Constraints: [a-zA-Z0-9] max 50 chars
channel: an administrative grouping method for your entities.
Required in entity insert operation.
Constraints: [a-zA-Z0-9] max 50 chars
administrativeState: see administrativeStatevalues
Organization ID as URL parameter
In entity POST and PUT operations, OpenGate ignores the organisation field because its value is mandatory in the URL.
serviceGroup: Service configuration: configuration of services, operations available, etc.
Constraints: [a-zA-Z0-9] max 50 chars
Forbidden in bundle operations.
workgroup: the workgroup is the way to establish the relationships between devices and users. It’s used, for example, when you want to create software bundles.
Constraints: [a-zA-Z0-9] max 50 chars
This field only applies to OpenGate users.
plan (optional): an administrative concept that allows limiting the number of events sent by the device. This concept only applies to devices.
Constraints: [a-zA-Z0-9] max 50 chars
Forbidden in bundle operations.
Optional in entity insert and update operation.
Click to show administrative data as JSON document into a device entity…
It is of the utmost importance to select the correct entity service group. The service group you choose will determine how OpenGate behaves when managing your devices in the following ways:
Permitted operations.
This document outlines the process by which the platform transmits scheduled operations to devices.
Always: This type is designed for devices that are continuously connected. In this scenario, OpenGate will initiate operations on the devices in accordance with the pre-defined schedule. In the event that the target device is not connected, the operation will be cancelled and an error message will be generated.
On-session-connection: In this instance, the platform saves operations for subsequent use. Upon establishing a connection with the platform, the device will be notified of any pending operations and these will be sent to the device. This mode is applicable to devices utilising web sockets or MQTT connectors.
On-demand: In this instance, the device will request any outstanding operations. This approach enables devices to conserve battery power and retrieve pending operations when active.
Details
Should you wish for your devices to request all pending operations, you may utilise MQTT connections with the on-demand configuration.
Trusted boot: It is a requirement that all messages received by the platform include a field with the trusted boot value. In the absence of this field, OpenGate will reject the message.
Device security mode: This option allows you to select the desired security level for communications between the device and platform. The available options are:
None: communications are not encrypted.
Level 1: One-way authentication (or platform authentication). The platform is the sole entity responsible for authenticating itself to the client. It issues the client a certificate to confirm the platform’s authenticity.
At Level 2, both the client and the server authenticate themselves to each other, ensuring the veracity of the certificate presented by the platform.
At Level 3, both the client and the server authenticate themselves to each other, confirming the availability of the platform’s device certificate.
Service groups available on OpenGate cloud instance
As outlined in the organization’s plan, usage limits are to be established for the OpenGate platform. In the case of entities, if your organization has not defined a collection event limit, it must be set at the time of entity creation.
Flattened format
It is possible to create and search for data stream values (see default data models) using the flat format. This format is the same as that used on the South API. To indicate if data streams are in a flattened form, use the Boolean parameter ‘flattened’ in the URL.
The following examples demonstrate the process of transforming a hierarchical JSON format into a flattened JSON format. There are two types of values: simple and complex.
We will also demonstrate how to transform the existing normalised/flattened JSON examples into CSV format. The above examples will be joined together in a single CSV file comprising three lines, one for each example (a straightforward example and two complex examples).
Transforming the flattened format into CSV format is a relatively straightforward process, as the CSV file’s content adheres to the same guidelines as the flattened format. The first line (header) contains the name of the data stream, separated by “;”, and the following lines represent the different entities, with the field value of the data stream separated by “;” in the same order as the first line.
The following lines illustrate the format of a CSV file.
In the event that an entity contains a unique communication module, it is possible to indicate the name without the use of square brackets and without the inclusion of an identifier. In light of this, it can be seen that the two strings in question, namely [commsMod_battery_name(commsMod_battery_id)] and commsMod_battery_name, are identical.
Comprehensive API actions
Searching entities
This API enables the retrieval of a comprehensive list of entities, offering a multitude of options for:
Filtering (see Specific Filter Fields)
Sorting (see Sorting)
Selecting Required Fields (see Selecting)
Summarising (see Summary)
The results can be obtained in two distinct formats:
JSON Format (Default)
CSV Format
Additionally, the results can be obtained in a flattened format through the use of flattened parameters.
API specification
Subsections of Entities
Entity types & statuses
Entity type list
GATEWAY: M2M device like a concentrator or smart router, modem or gateway, etc.
ASSET: Business entity, usually have one or more devices connected.
COMMUNICATIONS_MODULE: Internal modem or interface for communications.
SUBSCRIPTION: Logical identifier for a communication channel as a GMS line.
SUBSCRIBER: Physical device associated with a Logical subscription.
Default device administrative statuses
REQUESTED: Entity requested to the supplier
READY: Entity ready for installation
REPAIR: Entity under repair
TESTING: Entity in tests
ACTIVE: Entity deployed on field
SUSPEND: Suspended its operation
DELETED: Entity removed from available stock
RETIRED: Entity retired from field
BANNED: Entity banned, no data is going to be collected for devices with this status
Alarms for BANNED entities
The default rules catalog has an automation rule to elevate an alarm when a BANNED device shows activity. Besides that, you can run a job or schedule a task over entities with a BANNED administrative state.
Device operational statuses
UNKNOWN: Not known
NORMAL: Normal Operation
ALARM: The device has active alarms
TESTING: The device is under test. Could be running but it is not performing its normal operation.
DOWN: The device is not operative. Could be running but it is not performing its operation.
SAFE_MODE: The device is in Safe Mode (Sleeping, etc.)
TAMPER: The device was tampered
TEST: The device is working in test mode
Communication modules operational status
UNKNOWN: The module status is not known
STOPPED: The module is not working
STARTING: The module is booting
RUNNING: The module is working
STOPPING: The module is shutting down
ERROR: The module has an error
Devices
Introduction
A device represents the physical element (communications devices, concentrators, machines, sensors, etc.) through which data is collected.
Relation between devices and assets
A device can be linked to an asset through the provision.device.related data stream, which must contain the identifier of the asset in question.
When these entities are related, the asset is able to collect data from the related device. In order to do this, it is necessary to define an available data model for the Devices and Assets resources, and then define all the data streams that you want to copy from the device. Once this has been done, the asset will then automatically start collecting these values from the device.
Comprehensive API actions
Creating a device
New devices can be created by sending a POST request that includes a correctly formatted JSON document in the body.
A device may contain or not contain subscriptions and subscribers. Furthermore, these can exist independently (please refer to create subscriptions or create subscribers for more information).
It is essential that the subscription or subscriber is located within the communication modules on the device. Consequently, there are various use cases for managing device relations, depending on whether there are existing subscriptions or subscribers.
The following options are available for creating a device:
Create a device without subscriptions or subscribers.
Create a device with subscriptions or subscribers that do not exist in the platform.
Create a device with subscriptions or subscribers that exist in the platform. In this instance, the following steps must be completed:
A device must be created (please refer to the ‘Create a device without subscriptions or subscribers’ section below for further details).
The device must then be updated with the relevant subscriptions or subscribers that are already present on the platform (please refer to the ‘Associate a subscription or subscriber to the device’ section below for further details).
Furthermore, a device can be linked to an asset. Please refer to the section entitled Relation between devices and assets for additional details.
Updating a device
Updates can be made to the following:
Device data
Device subscription or subscriber associations
Device subscription or subscriber disassociations
The JSON object passed will vary depending on the desired update.
Patching a device
It is possible to patch the following:
Only the device data
Associate a subscription or subscriber to the device
The JSON object passed will be different depending on the desired patch.
Furthermore, a device can be related to an asset. Please refer to the section entitled ‘Relation between devices and assets’ for more information.
Deleting a device
To delete a complete device with all associated subscriptions, send a DELETE request using the provided URL. The request should include a Boolean parameter, “full,” to indicate that you wish to delete the entire device.
Note
The default value of the field ‘full’ is set to ‘false’. In this case, if a device with a subscription or subscriber is deleted, only the device will be removed. Neither the subscription nor the subscriber will be deleted. After this, they will exist on the platform independently, without being associated with a device.
Searching device
This API enables the retrieval of a comprehensive list of devices, offering a multitude of options for:
Filter (See Specific Filter Fields)
Order (see Sorting)
Select Required Fields (see Selecting)
Summary (see Summary)
The results can be obtained in two different formats, as detailed in the HTTP Header Options.
JSON Format (Default)
CSV Format
As an alternative, the result can be obtained in a flattened format thanks to the flattened parameter (see device parameters).
API specification
Subscriptions
Introduction
A subscription stores information regarding the contracts with your communication operators. It can exist as a standalone entity or integrated within the device.
Comprehensive API actions
Patching a subscription
Please note that the administration channel value is mandatory for securitisation purposes in patch operation.
In the event of patching complex objects, any non-passed object attributes will be patched as non-existent. Therefore, it is advisable to include previous unchanged values to avoid any loss of data.
Searching subscriptions
The results can be obtained in two different formats, as detailed in the HTTP Header Options:
JSON Format (the default)
CSV Format
Searching subscriptions summary
The summary will always display the total counter, the organisation grouping counter and the channel grouping counter by default.
API specification
Subscribers
Introduction
The Subscriber Entity Store contains information regarding a specific communication channel. It can exist independently or within the device.
Comprehensive API actions
Patching a subscriber
Please note that the administration channel value is mandatory for securitisation purposes in patch operation.
In the event of patching complex objects, any non-passed object attributes will be patched as non-existent. Therefore, it is advisable to include previous unchanged values to avoid any loss of data.
Searching subscribers
The results can be obtained in two different formats, as detailed in the HTTP Header Options:
JSON Format (the default)
CSV Format
Searching subscribers summary
The summary will always display the total counter, the organisation grouping counter and the channel grouping counter by default.
API specification
Assets
Introduction
The software enables the creation of entities that are not devices, allowing users to emulate any type of entity they require, such as a worker or a spool.
Concurrently, a device may be associated with an asset. To illustrate, a worker may utilise a device that monitors a range of parameters.
These devices can take the form of a bracelet that monitors battery levels, pulse rate, temperature and position, or a vest that measures a range of other parameters.
An asset is able to identify its associated devices through the provision.asset.related data stream. This data contains an array of identifiers for the associated devices.
Should you wish to receive all information pertaining to the device in the asset, you must add a data model with dual data streams. Once both are related in this way, the assets will be able to receive all common data streams from the device. This ensures that all datastreams and data points collected will be in the cycle of life for both.
The platform is set up by default to offer the Entity data model, which contains two dual data streams: ’entity.location’ and ’entity.areas’. Please refer to the Default Datamodels section for more information.
Asset object structure
An asset is a repository of information about the new entity created by the user.
In regard to provisioned data, the following attributes are applicable:
Minimum attributes:
provision.administration.
provision.asset.identifier.
resourceType.
Recommended attributes by OpenGate:
provision.asset.administrativeState.
provision.asset.specificType.
provision.asset.name.
provision.asset.description.
Extended attributes:
provision.asset.location.
Defined attributes in human datamodel.
Defined by the user in his new datamodels. For example photo, position
Note
The specificType field is used to differentiate new entities. For instance, a worker is classified as an entity.asset with the specificType WORKER.
Comprehensive API actions
Creating an asset
New assets can be created by sending a POST request, including a correctly formatted JSON document in the POST body using the generic URL for entities
Please be advised that there is no requirement to include an organisation field in the JSON, as this information is already available in the URL.
It is not possible to create a list of devices associated with an asset. These must be added from the Devices section.
Updating an asset
Please be advised that an asset can be modified by sending a PATCH request using the generic URL for entities.
It is necessary to replace {identifier} with the identifier of the asset you wish to modify. Additionally, a boolean parameter, flattened, must be included to enable the sending of a flattened JSON format.
Warning
Please be advised that it is not possible to patch the list of devices associated with the asset. The devices must be patched from the list.
When patching complex object values, non-passed object attributes will be patched as non-existent. Therefore, it is advisable to include previous unchanged values to avoid any loss of data.
Please note that the Resource Type and Administration Channel values are mandatory in asset patch operations for securitisation purposes.
Deleting an asset
Note that it is not possible to delete the list of devices associated with an asset. Instead, you will need to delete them from the devices list.
Please be advised that an asset can be deleted by sending a DELETE request using the generic URL for entities.
The bulk function enables the provisioning of a list of entities or tickets in a single operation, in either synchronous or asynchronous mode.
Bulk Object Structure
Bulk requests and responses can be formatted in four different ways, which can be selected through the Content-Type HTTP header. The default format is JSON, but the other formats are also available:
CSV format
XLS Excel format
XLSX Excel format
Attaching Files as Multipart
The Async API enables the creation of multipart files. In this instance, the Content-Type HTTP header will be multipart/form-data, and the file type will be indicated in the attached content.
HTTP Header Options
The API enables the indication of the format in which the request content is to be sent, either JSON or CSV, via the HTTP header option “Content-Type”. Similarly, the API allows the indication of the format in which the response content is to be received, either JSON or CSV, via the HTTP header option “Accept”.
It is possible to send a request and receive a response in different formats. For example, a request sent in JSON format can be received in CSV format.
Content-type header
The bulk input can be provided in different formats, depending on the file type. The Content-Type header should indicate the format of the input data. The following formats are supported for both synchronous and asynchronous operations:
Please be advised that the bulk processing results will be created in the format indicated in the ACCEPT header of the POST call, for both synchronous and asynchronous operations. To achieve the desired result with the GET call, it is essential to ensure that the ACCEPT header is identical to that used in the POST call.
In the event that the POST is not completed with the correct MIME type in the ACCEPT header, an error message will be displayed. Similarly, if the GET is not completed with the correct MIME type in the ACCEPT header, the same error message will be displayed.
Comprehensive API actions
Synchronous bulk
Creating a synchronous bulk for entities
The Synchronous Bulk Creation process allows you to create multiple entities in a single request. This bulk operation applies to the following entities:
Assets
Devices
Subscriptions
Subscribers
Creating a synchronous bulk for tickets
The Synchronous Bulk Creation process for tickets allows you to create multiple ticket records in a single request.
Asynchronous bulk
Creating an Asynchronous bulk for entities
In the case of asynchronous calls, the POST method will return an empty body and the URL of the created bulk process in the Location header. To monitor the progress and outcome, a GET request should be made to the URL returned by the POST method.
Asynchronous searching
A comprehensive search is being conducted across all previously created bulk processes, whether completed or still in progress.
API specification
Provision functions for bulk provisioning
Limited access API
Limited access
Please note that the provision API of this feature is only available to the root profile. Similarly, the execution API (plan or bulk) of this feature is only available to the following profiles: root, admin, admin_domain, advanced and super_admin_domain. In contrast, the searching API is accessible to all users. Should you require further information, please consult your administrator.
Introduction
This API enables users to perform bulk provisioning using Provision Processors. These processors allow users to define their own Excel formatting using a JavaScript script, which adapts the formatting to align with the OpenGate APIs.
Provision Processor object structure
A Provision Processor will include a JSON object with a script field, which contains the JavaScript code responsible for processing inbound data and determining the appropriate actions for provisioning the relevant entities, such as JSON objects, devices, subscriptions and subscribers. When creating or updating a Provision Processor, only minimal parsing of the script will be performed.
Comprehensive API actions
Provision processors
Creating a provision processor
Please note that the Accept field should be set to application/JSON.
Updating a provision processor
All actions are based on application/JSON data formats.
Searching provision processors
Please search for all completed and ongoing bulk processes.
Executing provision processors
Executing plan from selected provision processor
As with the Bulk creation process, files will be attached as multipart, with only XLS and XLSX formats permitted.
In this instance, the Accept header must be set to application/JSON.
Rather than creating a bulk process, it would be more efficient to return the provision process planning for specified entries. This is a synchronisation process that does not result in changes to the database.
Executing bulk from selected provision processor
Files used for bulk processing will be attached to the request as multipart.
The attached file must contain a specific Content-Type property to indicate the format of the file.
Only XLS and XLSX formats are permitted.
The Accept header must match the attached file’s Content-Type.
Reading the bulk summary
Please note that the Accept field should be set to application/JSON.
Reading the bulk details from selected bulk
Please note that the Accept field should be the same used in the bulk creation request.
API specification
Subsections of Provision functions for bulk provisioning
JavaScript API
Introduction to provision processors
This API’s purpose is to facilitate the development of Provision Processors in the simplest possible way.
The API is divided into several modules/scripts:
Provision_Processor / provision_processor.js: This is the entry point from Java. It defines a template for Provision Processor execution.
Entities_Utils / provision_entity_utils.js: Utility class to facilitate the entities building.
Action_Utils / provision_actions_utils.js: Utility functions to create the actions to be returned to Java process.
V8_Api / provision_JavaV8_api.js: Functions used to invoke Java V8 methods.
V8_Utils / provision_JavaV8_utils.js: Some generic functions to use V8_API. When developing a new Provision Processor, instead of calling directly V8_Api functions is better to use the methods defined here.
Error_Api: Facility class to manage and transform caught OpenGate provision error.
Provision Processor
One Provision Processor is a script that, using Provision Javascript API, implements the business logic to transform inbound data into several actions to be done by Java to do correct provisioning actions.
How to Implement Provision Processor
When implementing a Provision Processor it is mandatory to implement two specific functions. These functions are called from Provision_Processor.processRow function:
normalizeRowMap(rawObject): This function receives a map with the data to be processed. For example, a map with the data read from an excel file. It takes the inbound parameter and transforms it into an object to be used to calculate and build the actions for this row. In this function, values validation and transformation should be done.
Input parameter: JSON object with raw keys and values.
Output: JSON object with the desired structure.
actionsPlanning(normalizedObject): Takes the result from normalizeRowMap function and calculates the actions to be done in Java.
Input parameter: Normalized object.
Output: Array of Actions.
It is possible to define extra functions to manage and transform provision errors. This function will be called from Main_Module.transformErrorMessage:
customErrorTransformer(errorManager): This function will be called when some provision error is caught (for example: duplicated entity). The goal is to create a customized error message for the Excel row update. This function is not mandatory, and if it is not defined, a default message will be returned by Main_Module.transformErrorMessage.
Input parameter: Object with error information (caught exception, failed action specification, and default message) and useful methods to manage this information.
Output: This function must return a String with the customized message.
Example of Provision Processor for creating devices and assets with some fields. It uses the functions and classes defined in Provision Javascript API.
/* *******************
MANDATORY FUNCTIONS
******************* */functionnormalizeRawObject(rawObject) {
try {
varnormalizedObject= {
/*
In this case, raw object data comes from an excel
and to specify the full key, we use the header name and column letter
*/organization:readMapValue(rawObject, 'Organization', '', 'A'),
channel:readMapValue(rawObject, 'Channel Name', '', 'B'),
/* maybe some values can be defined in the script as constants */service_group:'emptyServiceGroup',
/* We can do values validation and transformations. For example remove blanks from the value. */device_identifier:readMapValue(rawObject, 'Serial number', '', 'D').replace(/\s/g, ''),
asset_identifier:readMapValue(rawObject, 'Asset Id', '', 'C').replace(/\s/g, '')
};
returnnormalizedObject;
} catch (e) {
printLog('>> normalizeRawObject(): exception: '+e);
throwe;
}
}
functionactionsPlanning(normalizedObject) {
varactions= [];
/*
In this case, we will create an asset and a device.
In the case of the device, if it exists, we are going to update it.
*//* we check if the asset exists before creating it. */varassetExist=checkAsset(normalizedObject.asset_identifier);
if(!assetExist){
varassetEntity=generateAssetEntity(normalizedObject)
actions.push(CREATE_ASSET_ACTION(assetEntity));
}
/* we check if the device exists. */vardeviceExist=checkDevice(normalizedObject.device_identifier);
vardeviceEntity=generateDeviceEntity(normalizedObject)
if(!deviceExist){
actions.push(CREATE_DEVICE_ACTION(deviceEntity));
}else{
actions.push(UPDATE_DEVICE_ACTION(deviceEntity));
}
returnactions;
}
/* ******************************************
OPTIONAL FUNCTION for error transformation
****************************************** *//* This function will be called when a provision exception is caught to get a customized message for excel row update */functioncustomErrorTransformer(errorManager) {
return'This is customized message for error code: '+errorManager.getFirstErrorCode() +' and message: '+errorManager.getFirstErrorMessage();
}
/* *************************
Other auxiliary functions
************************* */functiongenerateDeviceEntity(normalizedObject) {
try {
vardeviceEntity=newEntity()
.addDatastream('provision.administration.channel', normalizedObject.channel)
.addDatastream('provision.administration.serviceGroup', normalizedObject.service_group)
.addDatastream('provision.administration.organization', normalizedObject.organization)
.addDatastream('provision.administration.identifier', normalizedObject.device_identifier)
.addDatastream('provision.device.related', normalizedObject.asset_identifier);
returndeviceEntity.entityJson;
} catch (e) {
printLog('>> generateDeviceEntity: Exception: '+e);
throwe;
}
}
functiongenerateAssetEntity(normalizedObject) {
try {
varassetEntity=newEntity()
.addDatastream('resourceType', 'entity.asset')
.addDatastream('provision.administration.channel', normalizedObject.channel)
.addDatastream('provision.administration.serviceGroup', normalizedObject.service_group)
.addDatastream('provision.administration.organization', normalizedObject.organization)
.addDatastream('provision.administration.identifier', normalizedObject.asset_identifier);
returnassetEntity.entityJson;
} catch (e) {
printLog('>> generateAssetEntity: Exception: '+e);
throwe;
}
}
Important tips when writing a Provision Processor script
To add the script to Provision Processor JSON, it is necessary to take into these rules:
For strings, use single quotes (’) instead of double quotes (")
Use block comments (/**/) instead of line comments (//)
Format the script in a unique line script.
Action format
actionsPlanning returns an array of objects specifying the action to be done. Actions must be built with the functions defined in Action_Utils. Just to see the output format and following the previous example:
Sometimes, it could be necessary to stop processing and abort all provision processes. For example, because some validation is not passed. In that case, an error must be thrown with a descriptive message. For example:
functionactionsPlanning(normalizedObject) {
varactions= [];
...
if(!someValidation(normalizedObject)){
thrownew Error("Provision Processor Error: some validation not passed");
}
...
returnactions;
}
Main Module
Main Module
Main Script: Defines Provision Processor template to be called from Java
Global parameter with a received map of params from the java process.
This parameter is set at the beginning of processRow and it can be used in any function in the script.
This is the function that will be called from the Java process.
To work correctly this function, it is mandatory to implement in the provision processor script the following functions:
normalizeRowMap(rawObject): This function will read and transform inbound rawObject and transform to normalizedObject object that will be used in actionsPlanning() function.
actionsPlanning(normalizedObject): This function has to apply business rules and calculate the actions array to be done by the Java process.
Kind: inner method of Main_Module Returns: String - Json with following properties:
scriptDirectResult: OK or descriptive error text,
actionsToDo: Array with the list of Actions to be done in Java Process. This array can be empty.
Param
Type
Description
rawObject
Object
Json with excel row data
processorParamsMap
Object
Processor extra params map: can contain necessary parameters for odm api calls (key, organization) or useful parameters to define specific behaviors
Init entityJson property with an entity identifier. Use new Entity(entityIdentifier) to create a new Entity.
Param
Type
Description
entityIdentifier
String
identifier for current entity.
Example of use:
constentity=newEntity("entityIdentifier");
entity.withPrefix(prefixToBeUsed)
Define the prefix of the datastreams to be used by addDatastream method.
Adding a new prefix will override the previously added one.
Use this method with an empty or undefined parameter to stop using any prefix.
Kind: instance method of Entity Returns: Entity - Current Entity instance
Param
Type
Description
prefixToBeUsed
String
The prefix that will be used in next addDatastream calls. If it is empty the prefix will be removed.
Example of use:
entity.withPrefix("prefix");
entity.getDatastream(datastream, _index)
Search specified datastream and returns value. This function requires always complete datastream (ignores withPrefix functions calls).
Kind: instance method of Entity Returns: * - Found datastream’s value, it can be complex. Null if not found.
Param
Type
Description
datastream
String
Datastream complete flattened name.
_index
String
If datastream is an array, index should be provided, if not, first element will be returned.
Example of use:
entity.getDatastream("datastream");
entity.deleteDatastream(datastream, _index)
Delete specified datastream. This function requires always complete datastream (ignores withPrefix functions calls).
Kind: instance method of Entity Returns: * - Found datastream’s value, it can be complex. Null if not found.
Param
Type
Description
datastream
String
Datastream complete flattened name.
_index
String
If datastream is an array, index should be provided, if not, first element will be returned.
Example of use:
entity.deleteDatastream("datastream");
entity.addDatastream(datastream, value, _index)
Method to be used to add datastreams to current entity.
Calling this method more than one time for the same datastream will have two different behaviors:
If _index parameter is defined, a new value will be added or updated to the array.
If _index parameter is not defined, the previous datastream will be overridden.
Kind: instance method of Entity Returns: Entity - Current Entity instance
Param
Type
Description
datastream
String
Datastream flattened name.
value
String
Value for the datastream.
_index
String
If provided, it will create special indexed datastream (for communicationModules[] datastreams).
Example of use:
entity.addDatastream("datastream", "value");
entity._addToEntity(datastream)
Internal method.
Attach provided datastream to current Entity’s JSON.
Kind: instance method of Entity Returns: Entity - Current Entity instance.
Internal method.
Generates an object with datastream as field and provided array as value.
This method is helpful for communicationModules[] datastreams.
Internally calls _cleanArray method to add good array.
Kind: instance method of Entity Returns: Object - Json object with built datastream.
Internal method.
Generates an object with datastream as field and provided value.
In this case, value can be a plain value (for example, String) or a complex JSON
Internally calls _generateJsonCurrentValue to build basic json structure.
Kind: instance method of Entity Returns: Object - Json object with built datastream.
Auxiliary method to read values from the specified map.
A key will be created with headerName and headerColumn and the value for this key will be retrieved.
If there is no entry for this key or the value is empty or undefined, defaultValue will be returned.
If headerColumn is null, only headerName will be used as the key.
Kind: inner method of Entities_Utils Returns: * - Obtained value for specified header name and column or at least defined default value.
Param
Type
Description
map
Object
map from which to read values.
headerName
String
Header name for mapped row.
defaultValue
*
If no value is read or it is empty or undefined, default value will be returned.
headerColumn
String
Header column letter for mapped row (if null, only headerName will be used as key).
Internal method.
Searches for duplicated datastreams in other entities than the specified one.
Kind: inner method of V8_Utils Returns: boolean - If duplicated Datasteams are found in other entities.
Param
Type
Description
currentEntityIdentifierDatastream
String
Datastream used to specify the Entity id with the datastreams to be checked.
currentEntityIdentifierValue
String
Value for currentEntityIdentifierDatastream field.
…datastreamsToCheck
Object
Datastreams to be checked if they are duplicated. Each datastream is defined as a pair {“datastreamId”: “datastreamValue”}.
Example of use:
if (_checkDuplicatedDS(normalizedObject.subscription_identifier, normalizedObject.subscription_identifier, normalizedObject.datastreams)) {
printLog('Check returned true');
}
Error API
Error_Api
This module contains ErrorManager class specification.
ErrorManager
Class used to manage and extract information from caught provision action exception.
Internally contains following objects:
platformErrors: list of ApiPlatformError representation.
Returns provision action type (POST, PUT, PATCH, DELETE) from OdmProvisionAction
Kind: instance method of ErrorManager Returns: string - It can be undefined or null.
Example of use:
varaction=errorManager.getAction();
errorManager.isPost()
Kind: instance method of ErrorManager Returns: boolean - true if provision action is POST.
Example of use:
varisPost=errorManager.isPost();
errorManager.isPut()
Kind: instance method of ErrorManager Returns: boolean - true if provision action is PUT.
Example of use:
varisPut=errorManager.isPut();
errorManager.isPatch()
Kind: instance method of ErrorManager Returns: boolean - true if provision action is PATCH.
Example of use:
varisPatch=errorManager.isPatch();
errorManager.isDelete()
Kind: instance method of ErrorManager Returns: boolean - true if provision action is DELETE.
Example of use:
varisDelete=errorManager.isDelete();
errorManager.getEntityType()
Returns provision entity type (asset, device, subscription, subscriber) from OdmProvisionAction
Kind: instance method of ErrorManager Returns: string - It can be undefined or null.
Example of use:
varentityType=errorManager.getEntityType();
errorManager.isSubscription()
Kind: instance method of ErrorManager Returns: boolean - true if provision entity is subscription.
Example of use:
varisSubscription=errorManager.isSubscription();
errorManager.isSubscriber()
Kind: instance method of ErrorManager Returns: boolean - true if provision entity is subscriber.
Example of use:
varisSubscriber=errorManager.isSubscriber();
errorManager.isDevice()
Kind: instance method of ErrorManager Returns: boolean - true if provision entity is device.
Example of use:
varisDevice=errorManager.isDevice();
errorManager.isAsset()
Kind: instance method of ErrorManager Returns: boolean - true if provision entity is asset.
Example of use:
varisAsset=errorManager.isAsset();
Rules
Introduction
A rule is primarily composed of conditions and actions. When a rule is defined, a rule type can be specified, which determines the structure of the rule.
DATASTREAM: This type of rule would be evaluated if data were collected in the South API.
OPERATION: This type of rule would be evaluated if an operation were executed on the Opengate platform.
EVENT: This type of rule would be evaluated if an event were sent to the Opengate platform.
Automation rules
The set of conditions and actions can be defined in EASY mode using a JSON structure, or alternatively, an advanced rule can be written in JavaScript code.
Easy mode
The “easy mode” allows users to define new rules using the JSON format. Firstly, the rule type must be specified, as this will determine the structure of the rule.
Data stream: If this option is selected, the rules engine will evaluate data stream rules if an entity is modified using the north OpenGate API or when OpenGate collects data through any of the south connectors. In this case, the data streams that the rule will use must be configured in the condition.
Operation: If this option is selected, the rules engine will evaluate operation responses after they have been managed by the OpenGate operations engine.
Configure data stream and parameters in the rule
It is possible to utilise data streams and parameter values within the configuration of rules. This can be done in a number of ways, including in conditions and some attributes in rule actions.
Further examples can be found in the schemas’ objects.
Comprehensive API actions
Updating a rule
All fields may be updated in accordance with the same validations as a POST request, with the exception of identifier, organisation and channel. Furthermore, an ADVANCED rule cannot be changed to EASY mode.
API specification
Subsections of Rules
Advanced Rules Mode
Rules in Advanced Mode
In advanced rules, you can write conditions and actions in javascript language.
In this javascript code, it is possible to call some defined functions to execute the same actions that you can do in easy mode. On the other hand, we also have some help functions. We will explain them below.
The main function will receive a flattened entity representation, adding the _received and _previous values to each datastream. The _received field is a simple object in provision datastreams and an array object in any other case.
You can open an alarm on device, subscription or subscriber identifier. With subEntityIdentifier you define selected identifier. If is undefined it will open on provision.administration.identifier identifier.
alarmName
String
Name that you want to see in opened alarm
ruleName
String
Name of rule that produce opening of alarm.
severity
String
Alarm severity. Values can be INFORMATIVE, URGENT or CRITICAL.
priority
String
Alarm priority. Values can be LOW, MEDIUM or HIGH.
alarmDescription
String
Alarm description.
extraInfo
String
Extra information.
Examples of use
This example open alarm apnMismatch to subscription.
Closes an alarm for the selected entity using rule name.
Kind: global function Returns: void
Param
Type
Description
entityIdDatastream
String
You can close an alarm on device, subscription or subscriber identifier. With entityIdDatastream you define selected identifier. If is undefined it will close on provision.administration.identifier identifier.
Closes an alarm for the selected entity using alarm name.
Kind: global function Returns: void
Param
Type
Description
entityIdDatastream
String
You can close an alarm on device, subscription or subscriber identifier. With entityIdDatastream you define selected identifier. If is undefined it will close on provision.administration.identifier identifier.
Deprecated: Use notification object functions instead.
Sends email notification to defined recipients.
Kind: global function Returns: void
Param
Type
Description
recipients
Array
Array of recipients to send email. This param has same format as defined in easy mode.
notificationName
String
Name of notification that will be received in subject field.
notificationBody
String
Mustache template with email’s body
ruleName
String
Name of rule that launch email request.
mailParameters
Object
Json object with key-value pairs that will be replaces in mustache evaluation.
Example of use:
The example send email to example@recipient.es with highTemperature notification.
parameters= {};
parameters['deviceIdentifier'] =getDatastreamFromEntity('device.identifier')._current.value;
parameters['deviceTemperature'] =getDatastreamFromEntity('device.temperature')._current.value;
addEmailNotification(['example@recipient.es'], 'highTemperature', 'Received high temperature from {{deviceIdentifier}} with value {{deviceTemperature}}', 'highTemperatureRule', parameters);
Deprecated: Use notification object functions instead.
Sends http notification to defined recipients.
Kind: global function Returns: void
Param
Type
Description
httpJson
Object
Same json that easy mode.
Example of use:
The example send http request to http://myService/request with highTemperature notification.
httpJson= {
'url':'http://myService/request',
'method':'POST',
'headers': {
'Content-type':'application/json' },
'queryParams': {
'deviceId':entity['provision.device.identifier']._value._current.value },
'body':'New alert received by high temperature received. Current value: '+entity['device.temperature']._value._current.value};
sendHttp(httpJson);
Deprecated: Use operation object functions instead.
Executes selected operation to received identifier.
Kind: global function Returns: void
Param
Type
Description
subEntityIdentifier
String
You can execute operation on device, subscription or subscriber identifier. With subEntityIdentifier you define selected identifier. If is undefined it will open on provision.administration.identifier identifier.
operationType
String
Operation Identifier. You can get this values getting operation catalog. Mandatory field. The rule will be created, but the operation will not.
operationTimeout
Number
Operation timeout in milliseconds. Default: 60000 milliseconds
jobUser
String
User apiKey that launch this operation. Mandatory field. The rule will be created, but the operation will not.
retries
Number
Operation retries number. Default: 0.
ackTimeout
Number
ACK timeout in milliseconds. Default: null.
retriesDelay
Number
Delay in seconds between retries. Default: null.
stopValue
Number
Stop value, this value depends of stop mode selected. Default: Operation timeout + 5000.
stopMode
String
Stop mode. Default: delayed. Possible values: date (stop value is a date in YYYY-MM-DDThh:mm:ssTZD format) and delayed (stop value is a time defined in milliseconds).
parameters
Object
This value is a json with accepted value in selected operation. You can see parameters getting operation catalog.
callback
String
URI where the result of the operation execution is received.
NOTE: The Job of the operation will be created with an active status by default.
Example of use:
The example execute REFRESH_PRESENCE operation to received device.
Cancels active delayed action produced by another rule activation.
Kind: global function Returns: void
Param
Type
Description
ruleName
String
Name of rule that produce delayed actions.
Example of use:
The example cancel delay of ‘highTemperatureRule’ rule.
cancelDelay('highTemperatureRule');
Alarm utils
Alarm
The alarm object is the main object for managing alarms.
alarm.open(alarmConfig)
Opens an alarm.
Returns: void
This function takes as parameter an object with the following fields:
Property
Type
Default
Mandatory
Description
subEntityIdentifier
String
entityId
No
You can open an alarm on device, subscription or subscriber identifier. With subEntityIdentifier you define selected identifier. If is undefined it will open on provision.administration.identifier identifier
alarmName
String
No
Name that you want to see in opened alarm
ruleName
String
No
Name of rule that produce opening of alarm
severity
String
‘INFORMATIVE’
No
Severity of alarm. Values can be INFORMATIVE, URGENT or CRITICAL
priority
String
‘LOW’
No
Priority of alarm. Values can be LOW, MEDIUM or HIGH
description
String
No
Alarm description
extraInfo
String
No
Extra information.
Example of use:
This example open alarm apnMismatch to subscription.
And this example open alarm highTemperature to device.
alarmConfigDevice= {
alarmName:"highTemperature",
ruleName:"highTemperatureRule",
severity:"URGENT",
priority:"MEDIUM",
description:"Device temperature is high"}
alarm.open(alarmConfigDevice);
alarm.closeByRuleName(closeByRuleConfig)
Closes alarm by rule name.
Returns: void
This function takes as parameter an object with the following fields:
Property
Type
Default
Mandatory
Description
ruleName
String
Yes
Rule name that open alarm.
entityIdDatastream
String
No
You can close an alarm on device, subscription or subscriber identifier. With entityIdDatastream you define selected identifier. If is undefined it will close on provision.administration.identifier identifier.
Example of use:
The example close alarm generated by highTemperatureRule to device.
This function takes as parameter an object with the following fields:
Property
Type
Default
Mandatory
Description
alarmName
String
Yes
Opened alarm name.
entityIdDatastream
String
No
You can close an alarm on device, subscription or subscriber identifier. With entityIdDatastream you define selected identifier. If is undefined it will close on provision.administration.identifier identifier.
Example of use:
The example close opened alarm apnMismatch to device.
The notification object is the main object for managing notifications.
notification.addEmailNotification(emailConfig)
Sends an email notification to defined recipients.
Returns: void
This function takes as parameter an object with the following fields:
Property
Type
Default
Mandatory
Description
jsRecipients
List
Yes
Array of recipients to send email. This param has same format as defined in easy mode
notificationName
String
Yes
Name of notification that will be received in subject field
notificationBody
String
Yes
Mustache template with email’s body
ruleName
String
Yes
Name of rule that launch email request
mailParameters
Object
No
Json object with key-value pairs that will be replaces in mustache evaluation
Example of use:
The example send email to example@recipient.es with highTemperature notification.
emailNotifConfig= {
jsRecipients: ['example@recipient.es'],
notificationName:'highTemperature',
notificationBody:'Received high temperature from {{deviceIdentifier}} with value {{deviceTemperature}}',
ruleName:'highTemperatureRule',
mailParameters: {
deviceIdentifier:getDatastreamFromEntity('device.identifier')._current.value,
deviceTemperature:getDatastreamFromEntity('device.temperature')._current.value }
}
notification.addEmailNotification(emailNotifConfig);
notification.addTrapNotification(trapConfig)
Sends an SNMP trap notification to defined recipients.
This function takes as parameter an object with the following fields:
Property
Type
Default
Mandatory
Description
jsRecipients
List
Yes
Array of recipients (<ip>:<port>) to send trap. This param has same format as defined in easy mode
jsVariables
Object
Yes
Map of variables. Each pair defines OID variable and sent value for this OID
notificationName
String
Yes
Name of notification
trapOID
String
Yes
OID of trap
enterpriseOID
String
Yes
OID of enterprise
ruleName
String
Yes
Name of rule
Example of use:
The example send trap to 25.35.98.5:8585 with highTemperature notification.
Sends an HTTP request notification to a specified URL.
Returns: void
This function takes as parameter an object with the following fields:
Property
Type
Default
Mandatory
Description
url
String
Yes
URL to which the HTTP request will be sent
method
String
Yes
HTTP method to be used for the request
headers
Object
No
Key-value pairs representing HTTP headers
queryParams
Object
No
Key-value pairs representing query parameters
body
String
No
Body of the HTTP request
Example of use:
The example sends http request to http://myService/request with highTemperature notification.
httpJson= {
'url':'http://myService/request',
'method':'POST',
'headers': {
'Content-type':'application/json' },
'queryParams': {
'deviceId':entity['provision.device.identifier']._value._current.value },
'body':'New alert received by high temperature received. Current value: '+entity['device.temperature']._value._current.value};
notification.sendHttp(httpJson);
Operation utils
Operation
The operation object is the main object for executing operations.
operation.execute(operationConfig)
Execute selected operation to received identifier.
Returns: void
This function takes as parameter an object with the following fields:
Property
Type
Default
Mandatory
Description
subEntityIdentifier
String
No
You can execute operation on device, subscription or subscriber identifier. With subEntityIdentifier you define selected identifier. Default: If is undefined it will open on provision.administration.identifier identifier.
operationType
String
Yes
Operation Identifier. You can get this values getting operation catalog. Mandatory field. The rule will be created, but the operation will not.
operationTimeout
Number
60000
No
Operation timeout in milliseconds.
jobUser
String
Yes
User apiKey that launch this operation. Mandatory field. The rule will be created, but the operation will not.
retries
Number
0
No
Operation retries number.
ackTimeout
Number
null
No
ACK timeout in milliseconds.
retriesDelay
Number
0
No
Delay in seconds between retries.
stopValue
String
operationTimeout + 5000
No
Stop value, this value depends of stop mode selected.
stopMode
String
delayed
No
Stop mode. Possible values are: date: If this mode is selected, stop value is a date in YYYY-MM-DDThh:mm:ssTZD format. delayed: If this mode is selected, stop value is a time defined in milliseconds.
parameters
Object
{}
No
This value is a json with accepted value in selected operation. You can see parameters getting operation catalog.
callback
String
null
No
URI where the result of the operation execution is received.
NOTE: The Job of the operation will be created with an active status by default.
Example of use:
The example execute ADMINISTRATIVE_STATUS_CHANGE operation to received device.
This function returns date with current date, but with 2:00:00 hours. For example, if current day is 2021-06-30, the returned date in previously called function is 2021-06-30T02:00:00Z
getMonthlyResetDate()
Obtains date to reset monthly counters.
This function returns date with first day of current month and 00:00:00 hours.
Kind: global function Returns: Date
Example of use:
vardate=getMonthlyResetDate();
getMonthlyResetDateWithZuluHour(hour)
Obtains date to reset monthly counters with defined hour in gmt+0.
This function returns date with first day of current month, but with 2:00:00 hours. For example, if current day is 2021-06-30, the returned date in previously called function is 2021-06-01T02:00:00Z
This function returns date of the day 21 of current month, but with 2:00:00 hours, when day of the month is null, then return first day of the month. For example, the returned date in previously called function is 2023-02-21T02:00:00Z
Logging utils
Logging
The logger object is the main object for logging functions.
logger.trace(…msg)
Creates TRACE level logging messages. It concatenates msg parameters to compound message to be logged.
Returns: void
Param
Type
Description
msg
string
list of elements to be concatenated to generate the string message to be printed.
Example of use:
logger.trace('Operation sent to', host_var, ' and port ', port_var, '. Operation content: ', operation_var);
logger.debug(…msg)
Creates DEBUG level logging messages. It concatenates msg parameters to compound message to be logged.
Returns: void
Param
Type
Description
msg
string
list of elements to be concatenated to generate the string message to be printed.
Example of use:
logger.debug('Operation sent to', host_var, ' and port ', port_var, '. Operation content: ', operation_var);
logger.info(…msg)
Creates INFO level logging messages. It concatenates msg parameters to compound message to be logged.
Returns: void
Param
Type
Description
msg
string
list of elements to be concatenated to generate the string message to be printed.
Example of use:
logger.info('Operation sent to', host_var, ' and port ', port_var, '. Operation content: ', operation_var);
logger.warn(…msg)
Creates WARN level logging messages. It concatenates msg parameters to compound message to be logged.
Returns: void
Param
Type
Description
msg
string
list of elements to be concatenated to generate the string message to be printed.
Example of use:
logger.warn('Operation sent to', host_var, ' and port ', port_var, '. Operation content: ', operation_var);
logger.error(…msg)
Creates ERROR level logging messages. It concatenates msg parameters to compound message to be logged.
Returns: void
Param
Type
Description
msg
string
list of elements to be concatenated to generate the string message to be printed.
Example of use:
logger.error('Error connecting to host ', host_var, ' and port ', port_var, '. Stop processing');