Sending requests¶
Tap communication is based on a Lightweight M2M protocol, where the Tap device plays a role of a server and the mobile app an LwM2M client. Available commands are organized into services. See the list of services and functions.
There are two ways to send requests to your Tap:
- Service API: a developer friendly interface.
- Client API: a very basic low level interface.
Service API¶
The Service API is a wrapper on the IoTize Client API that lists availables services and handles sending requests building and binary parsing of responses.
If you want to send raw requests, you can use the client directly (see Client API)
Accessing service object¶
import { Tap } from '@iotize/device-client.js/device';
import {
BundleService,
TargetService,
FirmwareService,
} from '@iotize/device-client.js/device/service';
let tap: Tap;
let bundleService: BundleService = tap.service.bundle;
let targetService: TargetService = tap.service.target;
let firmwareService: FirmwareService = tap.service.firmware;
// ...
import com.iotize.android.device.device.impl.IoTizeDevice;
import com.iotize.android.device.device.api.service.definition.BundleService;
import com.iotize.android.device.device.api.service.definition.FirmwareService;
import com.iotize.android.device.device.api.service.definition.TargetService;
IoTizeDevice tap = // ... ;
// Access different services:
BundleService bundleService = tap.service.bundle;
TargetService targetService = tap.service.target;
FirmwareService firmwareService = tap.service.firmware;
// ...
let tap: TapDevice = // ... ;
// Access different services:
let bundleService: BundleService = tap.service.bundle;
let targetService: TargetService = tap.service.target;
let firmwareService: FirmwareService = tap.service.firmware;
Performing calls¶
You can make synchronous or asynchronous calls to the tap device.
Synchronously¶
// Only available if you are in an ASYNC function
let response: Response<string> = await tap.service.device.getSerialNumber();
Call<String> call = tap.service.device.getSerialNumber();
Response<String> response = call.execute();
let response: ApiResponse<String> = try tap.service.device.getSerialNumber();
Asynchronously, with callbacks¶
import { Response } from '@iotize/device-client.js/client/api/response';
import { Tap } from '@iotize/device-client.js/device';
let tap: Tap; // Init you tap instance...
let responsePromise: Promise<Response<string>> =
tap.service.device.getSerialNumber();
responsePromise
.then((response: Response<string>) => {
console.log('Device response:', response);
})
.catch((error) => {
console.error('An error occured:', error);
});
Call<String> call = tap.service.device.getSerialNumber();
commandCall.enqueue(new ICallback<String>() {
@Override
public void onResponse(Call<String> call, Response<String> response) {
// Do what you need here
}
@Override
public void onFailure(Call<String> call, Throwable throwable) {
Log.e("yourlogtag", "Error occured: " + throwable.getMessage(), throwable);
}
});
// Not available yet
Client API¶
Command format¶
LwM2M frames are composed by:
- header: command type (GET, PUT or POST) and command path string with
<Object ID>/<Object Instance ID>/<Resource ID>
. - payload: in bytes.
Building a command¶
Commands are built by a Command
Object. You can use helper methods to instantiate it according to the request type you want to use.
import { ApiRequest } from '@iotize/device-client.js/client/impl/request';
// Get request
let getRequest = ApiRequest.GET('/1/2/3');
// Put request with body 0x01020304
let putRequest = ApiRequest.PUT('/1/2/3', Uint8Array.from([1, 2, 3, 4]));
// Post request with body 0x01020304
let postRequest = ApiRequest.POST('/1/2/3', Uint8Array.from([1, 2, 3, 4]));
import com.iotize.android.device.api.client.request.Command;
// Get command
Command command = Command.GET("/1/2/3")
// Put command
Command command = Command.PUT("/1/2/3")
// Post command
Command command = Command.POST("/1/2/3")
import TapDeviceClient
// Get command
let request = ApiRequest.GET<Bytes>(path: "/1/2/3")
// Put command
let request = ApiRequest.PUT<Bytes>(path: "/1/2/3")
// Post command
let request = ApiRequest.POST<Bytes>(path: "/1/2/3")
Handling Response¶
A response is composed of
- result code: See the list of result code returns by a Tap.
- payload (optionally): encoded data (
bytes
)
A Response
can be configured with a Converter
class to decode bytes into the corresponding type. If you are using the Service API, Response
is preconfigured with the proper Converter
instance. We suppose in the following examples that we have a response for the getSerialNumber command which returns an ASCII string.
import { Response } from "@iotize/device-client.js/client/impl/response"
let response: Response<string> = //...;
if (response.isSuccess()){
// If you are using Service API
let serialNumber = response.body();
// Or if you build request with the client, you can give the converter type
let serialNumber = resonse.body(StringConverter.instance());
}
else {
// Handle invalid response
console.error(`Response error: ${response.codeRet()}`);
}
import com.iotize.android.device.api.client.response.Response;
Response<String> response = // ...;
// Check if command was successful
if (response.isSuccessful()){
String serialNumber = response.body();
Log.i("yourlogtag", "Serial number is : " + serialNumber);
}
else{
// If command is not successful we can check error code to know why
Log.w("yourtag", "Iotize error code: " + response.codeRet());
}
let response: ApiResponse<String> = // ...;
if (response.isSuccessful()){
let serialNumber: String = response.body();
print("Serial number is : \(serialNumber)");
}
else{
// If command is not successful we can check error code to know why
print("Iotize error code: \(response.codeRet()");
}
You can also access raw body (without any decoding)
let body: Uint8Array = response.rawBody();
byte[] body = response.rawBody();
let bytes: Bytes = response.rawBody()