Handling Binary transformation
As many devices use binary encoded payloads, the MQTT script engine provides support for handling of this type of data. When the device sends a binary data, the script will decrypt the binary data and converts it into an acceptable format.
The script supports encode and decode functions. Encode function is for mapping the binary format data for the downlink request like read or write and the decode function is for processing the uplink request from the devices.
For downlink, before the data is sent to the device, the device script will convert or encode data into binary format and sends to the device.
For sample payload, see Sample Uplink Payload.
For Binary script samples, see Binary uplink codec scripts and Binary downlink codec scripts.
Sample Uplink Payload
TOPIC:
device/device01
PAYLOAD:
7b226d616e756661637475726572223a2247656e65726963222c20226d6f64656c223a2253656e736f72222c226669726d7761726556657273696f6e223a22312e30222c202262617474657279223a22313031222c202274656d7065726174757265223a223333227d
Binary uplink codec scripts
Binary_codec.js script
var utils = Java.type('com.nokia.adapter.transformation.utils.TranformerUtil');
function GenericSensorCodec() {
const MANUFACTURER = 'device/0/manufacturer';
const MODEL = 'device/0/model';
const FIRMWARE_VERSION = 'device/0/firmwareVersion';
const TEMPERATURE = 'sensor/0/temperature';
this.encode = function (impactRequest) {
console.log("input to BinaryRequestCodec encoder", impactRequest, typeof(impactRequest), impactRequest.toString());
var requestType = utils.getRequestType(impactRequest);
console.log('request type is ' + requestType);
switch(requestType){
case "READ":
var payload = { type: 'read', correlatorId: impactRequest.getCorrelatorId(),resourcepath: impactRequest.getResource()};
var hexData = string2Hex(JSON.stringify(payload));
console.log("Encoded binary payload", hexData);
var response = {resource: 'devices/'+impactRequest.getSerialNumber()+"/"+TEMPERATURE, payload: hexData};
return constructImpactDownlinkRequest(response);
case "WRITE":
var payload = { type: 'write', correlatorId: impactRequest.getCorrelatorId(), resourcepath: impactRequest.getResource(), value: impactRequest.getValue() };
var hexData = string2Hex(JSON.stringify(payload));
console.log("Encoded binary payload", hexData);
var response = {resource: 'devices/'+impactRequest.getSerialNumber()+"/"+TEMPERATURE, payload: hexData};
return constructImpactDownlinkRequest(response);
}
}
this.decode = function (decodeCtx) {
var bytes = decodeCtx.getUplinkMessage();
var request = bytes2String(bytes);
console.log("input to BinaryRequestCodec decoder", request);
var json = JSON.parse(request);
var payload = hex2String(json.payload);
console.log("Decoded payload", payload);
if(json.topic.includes("response")){
var responsePayload = JSON.parse(payload);
console.log('response type is ' + responsePayload.type);
var res = {};
if(responsePayload.type == "read"){
res[responsePayload.topic] = responsePayload.value;
var readResponse = {type: 'READ_RESPONSE', correlatorid: responsePayload.correlatorId, resources: res, status: 200};
return formImpactNotifyFromJson(decodeCtx, readResponse);
}else if(responsePayload.type == "write"){
res[responsePayload.topic] = responsePayload.value;
var writeResponse = {type: 'WRITE_RESPONSE', correlatorid: responsePayload.correlatorId, resources: res, status: 200};
return formImpactNotifyFromJson(decodeCtx, writeResponse);
}
} else {
var requestPayload = JSON.parse(payload);
var resources = {};
if (requestPayload.temperature) {
resources[TEMPERATURE] = requestPayload.temperature;
}
var resources = constructResourceMapping(requestPayload, resources);
var notifyResponse = {type: 'NOTIFY', resources: resources};
return formImpactNotifyFromJson(decodeCtx, notifyResponse);
}
}
function constructResourceMapping(payload, resources) {
if (payload.manufacturer) {
resources[MANUFACTURER] = payload.manufacturer;
}
if (payload.model) {
resources[MODEL] = payload.model;
}
if (payload.firmwareVersion) {
resources[FIRMWARE_VERSION] = payload.firmwareVersion;
}
return resources;
}
}
var codec = new GenericSensorCodec();
(codec);
Binary_util.js script
var utils = Java.type('com.nokia.adapter.transformation.utils.TranformerUtil');
function bytes2String(bytes, offset=0) {
if (offset < 0) { offset=0; }
var result = "";
for (var i = offset; i < bytes.length; i++) {
result += String.fromCharCode(bytes[i]);
}
return result;
}
function hex2String(str) {
var hex = str.toString();
var str = '';
for (var n = 0; n < hex.length; n += 2) {
str += String.fromCharCode(parseInt(hex.substr(n, 2), 16));
}
return str;
}
function string2Hex(str) {
var hex = '';
for (var i=0; i<str.length; i++) {
hex += str.charCodeAt(i).toString(16);
}
return hex;
}
function constructImpactDownlinkRequest(resp) {
var response = JSON.stringify(resp);
console.log('sending read request ' + response);
return utils.createMqttEncodeResponse(response);
}
function formImpactNotifyFromJson(decodeCtx, resources) {
var response = JSON.stringify(resources);
console.log('sending notify response ' + response);
return utils.createMqttDecodeResponse(response);
}
Binary downlink codec scripts
Binary_codec.js script
var utils = Java.type('com.nokia.adapter.transformation.utils.TranformerUtil');
function BinaryCodec() {
const MANUFACTURER = 'device/0/manufacturer';
const MODEL = 'device/0/model';
const FIRMWARE_VERSION = 'device/0/firmwareVersion';
const TEMPERATURE = 'temperature';
this.encode = function (impactRequest) {
console.log("input to BinaryRequestCodec encoder", impactRequest, typeof(impactRequest), impactRequest.toString());
var requestType = utils.getRequestType(impactRequest);
console.log('request type is ' + requestType);
switch(requestType){
case "READ":
var payload = { type: 'read', correlatorId: impactRequest.getCorrelatorId()};
var hexData = string2Hex(JSON.stringify(payload));
console.log("Encoded binary payload", hexData);
var response = {resource: 'device/'+impactRequest.getSerialNumber()+"/"+TEMPERATURE, payload: hexData};
return constructImpactDownlinkRequest(response);
case "WRITE":
var payload = { type: 'write', correlatorId: impactRequest.getCorrelatorId(), resourcepath: impactRequest.getResource(), value: impactRequest.getValue()};
var hexData = string2Hex(JSON.stringify(payload));
console.log("Encoded binary payload", hexData);
var response = {resource: 'device/'+impactRequest.getSerialNumber()+"/"+TEMPERATURE, payload: hexData};
return constructImpactDownlinkRequest(response);
}
}
this.decode = function (decodeCtx) {
var bytes = decodeCtx.getUplinkMessage();
var request = bytes2String(bytes);
console.log("input to BinaryRequestCodec decoder", request);
var json = JSON.parse(request);
var payload = hex2String(json.payload);
console.log("Decoded payload******", payload);
if(json.topic.includes("response")){
var payload = JSON.parse(json.payload);
console.log('payload---'+JSON.stringify(payload));
var payload = hex2String(payload.rawPayload);
console.log("Decoded payload++++++++", payload);
var responsePayload = JSON.parse(payload);
console.log('payload---'+JSON.stringify(responsePayload));
console.log('response type is ' + responsePayload.type);
var res = {};
if(responsePayload.type == "read"){
var readResource;
if(responsePayload.topic.includes("temperature")){
readResource = "sensor/0/temperature";
}
res[readResource] = responsePayload.value;
var readResponse = {type: 'READ_RESPONSE', correlatorid: responsePayload.correlatorId, resources: res, status: 200};
return formImpactNotifyFromJson(decodeCtx, readResponse);
}else if(responsePayload.type == "write"){
var writeResource;
if(responsePayload.topic.includes("temperature")){
writeResource = "sensor/0/temperature";
}
res[writeResource] = responsePayload.value;
var writeResponse = {type: 'WRITE_RESPONSE', correlatorid: responsePayload.correlatorId, resources: res, status: 200};
return formImpactNotifyFromJson(decodeCtx, writeResponse);
}
} else {
var requestPayload = JSON.parse(payload);
var resources = {};
if (requestPayload.temperature) {
resources[TEMPERATURE] = requestPayload.temperature;
}
var resources = constructResourceMapping(requestPayload, resources);
var notifyResponse = {type: 'NOTIFY', resources: resources};
return formImpactNotifyFromJson(decodeCtx, notifyResponse);
}
}
function constructResourceMapping(payload, resources) {
if (payload.manufacturer) {
resources[MANUFACTURER] = payload.manufacturer;
}
if (payload.model) {
resources[MODEL] = payload.model;
}
if (payload.firmwareVersion) {
resources[FIRMWARE_VERSION] = payload.firmwareVersion;
}
return resources;
}
}
var codec = new BinaryCodec();
(codec);
Binary_util.js script
var utils = Java.type('com.nokia.adapter.transformation.utils.TranformerUtil');
function bytes2String(bytes, offset=0) {
if (offset < 0) { offset=0; }
var result = "";
for (var i = offset; i < bytes.length; i++) {
result += String.fromCharCode(bytes[i]);
}
return result;
}
function hex2String(str) {
var hex = str.toString();
var str = '';
for (var n = 0; n < hex.length; n += 2) {
str += String.fromCharCode(parseInt(hex.substr(n, 2), 16));
}
return str;
}
function string2Hex(str) {
var hex = '';
for (var i=0; i<str.length; i++) {
hex += str.charCodeAt(i).toString(16);
}
return hex;
}
function constructImpactDownlinkRequest(resp) {
var response = JSON.stringify(resp);
console.log('sending read request ' + response);
return utils.createMqttEncodeResponse(response);
}
function formImpactNotifyFromJson(decodeCtx, resources) {
var response = JSON.stringify(resources);
console.log('sending notify response ' + response);
return utils.createMqttDecodeResponse(response);
}