Device ID and Payload Mapping in Uplink
Mapping Device ID in topic uplink
Device ID can be used within an MQTT topic to send uplink data. You can include the keyword "#deviceid" in the mapped topic name anywhere in the topic.
/devices/#deviceid/events
Parsing the device ID from the free format topic is a two-step process. The first step is to upload the device ID mapping script that helps you to parse the device ID from the topic. For more details, see DeviceIdMapper scripts.
The second step is to upload the actual scripts which do the parsing of the topic and do the mapping between the subscribed resources and the input topic given by the device. For more details, see GenericSensor_codec Scripts.
One IMPACT resource is mapped to one MQTT topic and one MQTT topic can have one IMPACT resource.
Topic Handling in Application Uplink
To interwork with generally available MQTT devices it is possible to use arbitrary topic names with no design limitation or predefine nomenclature rules when an Application subscribes to resources.
Example:
- The topic devices/dht114044500000001/Temperature is mapped
to Resource /sensor/0/Temperature which is subscribed by
the application.
The input topic is defined in the script. For example, if the input topic contains Temperature, it will be mapped to sensor/0/temperature which is subscribed by the application.
- The MQTT device is pre-provisioned with Manufacturer and Model of the
device.Note: Mapping scripts must be uploaded for each make and model.
- The Application SUBSCRIBE to Resource Name
/sensor/0/Temperature:
/m2m/subscriptions?type=resources { "resources": [ { "resourcePath": "sensor/0/temperature" } ], "groupName": "IMPACT", "subscriptionType": "resources", "deletionPolicy": 0 }
- The device initiates PUBLISH request:
Topic = devices/dht114044500000001 Payload = {"manufacturer":"Generic","model":"Sensor","firmwareVersion":"1.0","battery":"101", "temperature":"33"}
- The Application receives notification response:
value = {{{"reports":[{"serialNumber":"dht114044500000001", "timestamp":1639030617215, "subscriptionId":"c6f07af3-5a75-4ad5-91cd-b79fdc09fab0", "resourcePath":"sensor/0/temperature", "value":"33","customAttributes":{}, "protocol":"MQTT"}], "registrations":[], "deregistrations":[], "updates":[], "expirations":[], "responses":[]}}}
The topic is successfully mapped from the device to the subscribed topic by the application.
Sample script
var utils = Java.type('com.nokia.adapter.transformation.utils.TranformerUtil');
function DownlinkRequestCodec() {
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 DownlinkRequestCodec encoder", impactRequest, typeof(impactRequest), impactRequest.toString());
var requestType = utils.getRequestType(impactRequest);
console.log('request type is ' + requestType);
switch(requestType) {
case "WRITE":
var payload = {value: impactRequest.getValue(), correlatorId: impactRequest.getCorrelatorId(), type: 'write'};
var response = {resource: 'device/0/model', payload: JSON.stringify(payload)};
return constructImpactWriteRequest(response);
case "READ":
var payload = {correlatorId: impactRequest.getCorrelatorId(), type: 'read'};
var response = {resource: 'device/0/model', payload: JSON.stringify(payload)};
return constructImpactWriteRequest(response);
default:
throw "invalid request type provided";
}
console.log('exiting the script');
return "";
}
this.decode = function (decodeCtx) {
var bytes = decodeCtx.getUplinkMessage();
var request = bytes2String(bytes);
console.log("input to DownlinkRequestCodec decoder", request);
var json = JSON.parse(request);
if(json.topic.includes("response")){
var payload = JSON.parse(json.payload);
console.log('response type is ' + payload.type);
var res = {};
if(payload.type == "write"){
res[MODEL] = payload.value;
var writeResponse = {type: 'WRITE_RESPONSE', resources: res, correlatorid: payload.correlatorId, status: 200};
return formImpactNotifyFromJson(decodeCtx, writeResponse);
} else if(payload.type == "read"){
res[MODEL] = payload.value;
var readResponse = {type: 'READ_RESPONSE', resources: res, correlatorid: payload.correlatorId, status: 200};
return formImpactNotifyFromJson(decodeCtx, readResponse);
}
}
var resources = constructResourceMapping(json);
var notifyResponse = {type: 'NOTIFY', resources: resources};
return formImpactNotifyFromJson(decodeCtx, notifyResponse);
}
function constructResourceMapping(json) {
var payload = JSON.parse(json.payload);
var response = {};
if (payload.manufacturer) {
response[MANUFACTURER] = payload.manufacturer;
}
if (payload.model) {
response[MODEL] = payload.model;
}
if (payload.firmwareVersion) {
response[FIRMWARE_VERSION] = payload.firmwareVersion;
}
if (payload.temperature) {
response[TEMPERATURE] = payload.temperature;
}
return response;
}
}
var codec = new DownlinkRequestCodec();
(codec);