Record Architecture

Overview

Records are opposite of the Messages, messages in turn are static in nature, once the platform receives a message, it gets stored in its default storage indices and none of the attributes can be changed afterwards. Record is a dynamic storage where you can insert and perform CRUD operations at run time. You can equate a record structure as a database table where you can store and query data to build your business and functional logics. Boodskap by default, stores the record into Elasticsearch indexes.

Most IoT use cases requires to process the incoming data, add more semantics to it and store them for visual inspection, alert generation, AI & ML processing. Let’s take the same example data and extend it, let our use-case be, storing a snapshot of the last received message from each sensor and then store all the messages received from all sensors to build a status and historical chart / UI. In this case, we need to define two records

Example: Weather Sensor Status & History Record Structure

{
  "sensorid": "varchar",
  "receivedstamp": "timestamp",
  "latitude": "double",
  "longitude": "double",
  "temperature": "integer",
  "humidity": "integer",
  "precipitation": "integer",
  "wind": "integer"
}

📘

Record ID

Each record structure you create will have unique ID field called 'id' which will be automatically assigned, and by default its's data type is 'text'

Definition

Record structures can be defined very similar to the message definition. The above record structure can be defined in the platform like the image shown below. Menu => Home -> Record Definition -> Define Record. Once you have one or more records defined, you could start pushing records from rules engine or directly from IoT devices, or through API. In the above example, we have defined two records with an unique record identifiers as 2000 and 3000

14401440

Record Definition

Data Manipulation

Boodskap has multiple interfaces to work with records, to keep things simple, here we are going to see how to insert and query in the Rules Engine module. The objective is, as soon as a weather data arrives, we are going to insert a new record into the history (3000) table and upsert (insert or update) the status table (2000). In order to do that, we are going to use the Record Context object.

Example Rules Engine Script

def values = [:];

values['sensorid'] = msg.deviceid;
values['receivedat'] = util.millis();
values['latitude'] = msg.latitude;

values['latitude'] = msg.latitude;
values['longitude'] = msg.longitude;
values['temperature'] = msg.temperature;
values['humidity'] = msg.humidity;
values['precipitation'] = msg.precipitation;
values['wind'] = msg.wind;

// insert into history table
// each record gets a unique id, so the table keeps growing
record.insert(3000, util.uuid().toString(), values);

// insert/update into status table
// record gets updated every time with deviceid as the unique key
record.insert(2000, msg.deviceid, values);

Direct Access

In certain use cases, you may want to insert data directly into records from your IoT devices or through API, you could do it easily with this simple rest API. This could come in handy if you have more intelligent edge devices which has already curated/processed the data and simply wants to store the result into indexes for further processing or building UI/UX applications


Worth Seeing