In this article
Categories

N2N NNNCo uplink via https POST integration

Print

Connecting the NNNCo N2N DL platform to AlphaX Cloud via https:// POST protocol.

The N2N DL platform is a platform for connecting and managing data and devices on the NNNCo LoRaWAN network.

The platform provide multiple methods for transferring data to upstream applications. In this article we will explore using the https POST protocol which provides the easiest method for integration.

Assumptions
  • Devices are connected and communicating via the N2N DL platform*
  • You have access to perform integrations in the N2N DL platform*
  • You have enabled https integrations within AlphaX Cloud and generated a conduit token

* For assistance with the N2N DL platform please contact NNNCo.

For help generating an AlphaX Conduit token see this help article.

Configuring N2N DL Platform

Log-in to your NNNCo N2N DL portal using your username and password. Please contact NNNCo for these details if they have been lost or misplaced.
When you have gained access to the platform navigate to the subscriptions menu at the top menu bar. You will be redirected to a page that looks similar to the one shown below.

If you do not have an existing subscription in your menu – that is ok we will create on in the following steps.

  1. Click the plus button in the subscriptions tab.
  2. A form will be displayed for you to complete as shown below. Complete the form with the following minimum information.
  3. Select your enterprise from the drop down list. This will change depending on your NNNCo subscription
  4. Select the https subscription type.
  5. Enter “https://conduit.alphax.cloud/post/n2n-dl” into the http url field. Note the postv2 represents the format of the data that AlphaX expects. Please contact support for alternate packet formats.
  6. Add token:”AlphaX Token” to the http headers section. To get your AlphaX token please refer to this help article: How to Activate Conduit
  7. Click the create subscription button.

If you have been successful you will now see a new subscription in the subscriptions tab. This window provides the ability to click into the subscription to check the status and recent history of the subscription.

Configuring Data

The next step is to configure your data to be in the correct format. The integration will take care of the rest of the formatting automatically however, your data must be aligned to the correct channelId to be successfully imported into AlphaX. The unique identifier for registration into AlphaX is the device Id

There are two mandatory fields that are required for the integration into AlphaX to work.

  • channelId: integer Formated
  • value: Number Formatted (16 character maximum length)

Note: As seen above your sensor will require a different parser depending on make and model. Please refer to the manufacturer for information regarding packet format.

Example Parser: Variable Length Payload Length for X1 Series.
function parseDeviceMsg(buf:Buffer, loraMsg:LoraMessage):ParserReading[] {

let dynamic = [];

var i;
for (i=0; i < (buf.length-8)/4; i++){ dynamic.push({channelId:parseInt(i+1), value: buf.readUInt32LE(8+(i*4))/1000}); } dynamic.push({channelId: 252, value:buf.readUInt16LE(6)}); dynamic.push({channelId: 253, value:buf.readUInt16LE(4)}); dynamic.push({channelId: 254, value:buf.readUInt16LE(2)}); dynamic.push({channelId: 255, value:buf.readUInt16LE(0)/1000}); return dynamic; } Simple payload RisingHF function parseDeviceMsg(buf:Buffer, loraMessage:LoraMessage) { if(buf.length != 9) throw new Error(`Invalid payload length. Expected exactly 9 bytes. Got ${buf.length}`); let status = buf.readUInt8(0); if(status !== 0x81 && status !== 0x01) throw new Error(`Invalid payload. Status can be 0x81 = OK or 0x01 = NO_DOWNLINK. Got 0x${status.toString(16)}`); let temperature = ((buf.readInt16LE(1) * 175.72) / 65536) – 46.85; let humidity = ((buf.readUInt8(3) * 125) / 256) -6; let periodSec = buf.readInt16LE(4) * 2; let rssi = buf.readUInt8(6) – 180; let snr = buf.readUInt8(7) / 4; let vcc = (buf.readUInt8(8) + 150) / 100; return [ {channelId: 1, type: ReadingType.digital, value:status, label:’status’}, {channelId: 2, type: ReadingType.temperature, value:+temperature.toFixed(2), unit:’°C’, label:’temperature’}, {channelId: 3, type: ReadingType.humidity, value:+humidity.toFixed(2), unit:’%’,label:’humidity’ }, {channelId: 4, type: ReadingType.time, value:periodSec, unit:’s’,label:’uplink’}, {channelId: 5, type: ReadingType.loraRssi, value:+rssi.toFixed(2),unit:’dB’,label:’signal-strength’}, {channelId: 6, type: ReadingType.loraSnr, value:+snr.toFixed(2),unit:’dB’, label:’singal-to-noise’}, {channelId: 255, type: ReadingType.voltage, value:+vcc.toFixed(2), unit:’V’, label:’battery’}, ] }

Example Parser: Bitwise payload – Netvox device R311A
function parseDeviceMsg(buf:Buffer, loraMsg:LoraMessage) { if(buf.length != 11) throw new Error(`Invalid payload length. Expected exactly 11 bytes. Got ${buf.length}`); if(buf.readUInt8(0) !== 0x01) throw new Error(`Invalid payload structure: expected loraWAN version 0x01 for byte 0, got => ${buf.readUInt8(0).toString(16)}`);

// this is for R311A
let expectedTypeCode:number = 0x02;

if(buf.readUInt8(1) !== expectedTypeCode)
throw new Error(`Invalid payload structure: expected sensor type ${expectedTypeCode}, got => ${buf.readUInt8(1).toString(16)}`);

if(buf.readUInt8(2) !== 0x01)
throw new Error(`Invalid report type ${buf.readUInt8(2)}, expected 0x01 got => ${buf.readUInt8(2).toString(16)}`);

if(buf.readUInt8(4) !== 0x01 && buf.readUInt8(4) !== 0x00)
throw new Error(`Invalid payload structure: expected contact switch to be either 0x00 or 0x01, got => ${buf.readUInt8(4).toString(16)}`);

let lowVoltage = (buf.readUInt8(3) & 0x80) === 0x80 ? true : false;
let voltage = (buf.readUInt8(3) & 0x7F)/10; // byte 3

let openContact = buf.readUInt8(4) === 0x01 ? false : true;

return {
{ channelId: 1, type:ReadingType.boolean, value: openContact ? 1 : 0, label:’open-contact’},
{ channelId: 2, type:ReadingType.boolean, value: lowVoltage, label:’low-battery’}
{ channelId: 255, type:ReadingType.voltage, value: voltage, label:’battery’, unit:’V’},
}
}