Skip to content

TapNPass extension

This guide is for TapNPass device.

This contains functions to easily read/write data with your TapNPass device.

Warning

This extension is currently only available for typescript users

Prerequesities

Install @iotize/device-client.js

See README.md.

Install @iotize/device-ext-tapnpass.js

See README.md.

You have configured your Tap for serial communication

See Serial communication guide for more details.

Usage

Instantiate

import { TapNPass, MAX_ADP_BUFFER_SIZE } from '@iotize/device-ext-tapnpass.js';
import { Tap } from '@iotize/device-client.js/device';

let tap: Tap;

// Init with default options
let tapnpass: TapNPass = TapNPass.fromTap(tap);

// Init with custom options
let myOptions: TapNPass.Options = {
  // this option is only used when using inflate/deflate
  // This is the duration (in milliseconds) between two inflated/deplated packets
  interframe: 200,
  // Write data chunk size in bytes
  // Maximum size will depend on the communication protocol used
  writeChunkSize: 230,
  // Maximum buffer size (in bytes)
  maxBufferSize: MAX_ADP_BUFFER_SIZE,
};
let customTapnpass: TapNPass = TapNPass.fromTap(tap, myOptions);

writeChunkSize option

If you are using encryption with initialization vectors, the writeChunkSize has to be reduced as encryption add additional bytes to the request.

Write data

This sample show you how to write data.

import { TapNPass } from '@iotize/device-ext-tapnpass.js';

let tapnpass: TapNPass;

// Write ASCII string
await tapnpass.write('Hello World!');

// Write data
await tapnpass.write(new Uint8Array(500));

// Write with progress
let data: Uint8Array = new Uint8Array(0); // Your data ...
tapnpass.write$(data).subscribe((event: TapNPass.WriteEvent) => {
  console.log(
    `Write ${event.chunk.length} bytes. Chunk n°${event.current}/${event.total}`
  );
});

Tips

As it returns an Observable, you can benefit of rxjs power to add extra features such as retry or timeout.

Read data

This sample show you how to read data.

import { TapNPass } from '@iotize/device-ext-tapnpass.js';
import { Lenght, NoMoreData } from '@iotize/device-ext-tapnpass.js/operators';

let tapnpass: TapNPass;
let data: Uint8Array;

// Read the whole buffer
data = await tapnpass.read();
data = await tapnpass.read(NoMoreData);

// Read 34 bytes
data = await tapnpass.read(Lenght(34));

// Read until custom condition is met
let myCondition: TapNPass.ReadStopCondition = (
  chunk: Uint8Array,
  total: number
) => {
  return true;
};
data = await tapnpass.read(myCondition);

// Read with compression data
data = await tapnpass.read(NoMoreData, {
  inflate: true,
});

// Read with progress
tapnpass.read$(NoMoreData).subscribe((event: TapNPass.ReadEvent) => {
  if (event.chunk) {
    console.log(`New chunk read: ${event.chunk.length} bytes`);
  }
  if (event.result) {
    console.log(`Read complete! Received ${event.result.length} bytes`);
  }
});

Limitation

Your TapNPass buffer has a maximum capacity of 56KB. By default, both reception and transmission buffer sizes are set to 28KB. It will miss data when there are more than 28KB of received data. See Changing reception/transmission maximum buffer size

Multiple commands

To optimize communication speed, you can send multiple target commands and received multiple target responses in one request.

To use this feature, your commands must all ends with a specific delimiter character (2 bytes max). The same for your responses (4 bytes max).

See the following example

  • We suppose that a command ends with a new line ('\r\n') characters
  • We suppose a response ends with '%%' characters

Then the following script show you how to use multi command feature:

import { TapNPass } from '@iotize/device-ext-tapnpass.js';

let tapnpass: TapNPass; // ...

// First we need to configure delimiters
// This will tell your tapnpass how to separate multiple commands and multiple responses
await tapnpass.setCommandDelimiter('\r\n');
await tapnpass.setResponseDelimiter('%%');

// Then execute commands
let response = await tapnpass.commands([
  'my first command', // Do not add delimiters here, it's already done by the API
  'my second command',
]);
// it returns an array of responses (in the same order as your commands)
console.log(response);
// for example ['my first response', 'my second response']

// The same feature but with rxjs Observable
let observable = tapnpass.commands$(['my first command', 'my second command']);
observable.subscribe((event) => {
  console.log('New event', event);
});

Advance usage

Changing reception/transmission maximum buffer size

By default, reception and transmission buffer size are both 28KB (for a total of 56KBo data) but it can be changed with the API

import { TapNPass } from '@iotize/device-ext-tapnpass.js';
let tapnpass: TapNPass;

// Set transmission size to 34KB
await tapnpass.setTransmissionBufferSize(34);

import { TapNPass } from '@iotize/device-ext-tapnpass.js';
let tapnpass: TapNPass;

// Set reception buffer size to 43 KB
let receptionBufferSize = 43;
await tapnpass.setTransmissionBufferSize(56 - receptionBufferSize);

Warning

Increasing transmission buffer size will reduce the reception buffer size (or vice versa)

- If you use compression feature, maximum transmission buffer size is `41KB`
- Otherwise it's `55KB`

Reading Tapnpass stats

You can read various Tapnpass information using service tap.service.adp.getStatus().

import { TapNPass } from '@iotize/device-ext-tapnpass.js';
import { Tap } from '@iotize/device-client.js/device';

let tap: Tap; // ...

let adpStatus = (await tap.service.adp.getAdpStatus()).body();

// Display tapnpass version
console.log('Tapnpass version: ', JSON.stringify(adpStatus.header.version));

// Show USB state
console.log(
  'USB: ',
  adpStatus.state.usbDisconnected ? 'DISCONNECTED' : 'CONNECTED'
);

Full example

Below a full example of an app that will send "Hello World!" message and display the response.

import { TapNPass } from '@iotize/device-ext-tapnpass.js';
import { Tap } from '@iotize/device-client.js/device';
import { UartSettings } from '@iotize/device-client.js/device/model';
import { FormatHelper } from '@iotize/device-client.js/core/format/format-helper';

let tap: Tap; // ...

// Connect to the Tap
await tap.connect();

// Init TapNPass instance
let tapnpass = TapNPass.fromTap(tap);

let uartSettings: UartSettings = {
  baudRate: 9600,
  physicalPort: UartSettings.PhysicalPort.RS485,
  stopBit: UartSettings.StopBit.ONE_AND_HALF,
  bitParity: UartSettings.BitParity.EVEN,
  dataBitsLength: UartSettings.DataBitsLength._8,
  handshakeDelimiter: UartSettings.HandshakeDelimiter.CR_LF,
  handshakeValue: UartSettings.Handshake.RTS_CTS,
  timeout: 255,
  slv: 0,
  ofs: false,
};

// Configure uart
await tapnpass.setUARTSettings(uartSettings);

// You may need to login to use these features (according to your Tap configuration)
// tap.login("username", "password")

// Write message
await tapnpass.write('Hello World!');

// Read response
let response = await tapnpass.read((chunk, total) => total > 0);

console.info('Received response: ' + FormatHelper.toAsciiString(response));

Troubleshooting

Error UNAUTHORIZED

With the default configuration, serial port is protected. Only admin used can read/write data. Simply authenticate before using these features with tap.login("username", "password")

You can also change the configuration with IoTize Studio.

Errors starting with TARGET_PROTOCOL...

This error may occured in different cases. Here a list of possible reasons:

  1. You did not call tap.service.target.connect() before reading/writing data
  2. Your target device serial configuration is not the same as the one configured in your Tap device
  3. Your TapNPass is not properly configured to perform serial communication