Skip to content

Target variable

Target variable is a powerful feature of your Tap Device. You can easily expose variables from your target application and use the API to read, write and monitor them.

Prerequisities

What you need

  • Tap Device
  • IoTize Studio
  • Target Application that handles serial communications
  • Mobile Device with RF capabilities

You have iotized your target application variables

See steps to iotize your target application.

Configure your device object to work with variables

When you iotize your target application, IoTize Studio gives a unique identifier to your variables which it uses to access the corresponding resource in your Tap Device.

Tip

The variable identifier is found in IoTize Studio: IoTize Explorer / Bundles / <Your bundle> / <Your variable> / Variable Information / Id.

Manually

import { Tap } from '@iotize/device-client.js/device';
import {
  NumberConverter,
  UniqMaskConverter,
} from '@iotize/device-client.js/client/impl';

let tap: Tap; // ... instantiate your tap device...

// Configure your variables
tap.variables
  .add('temperature', {
    id: 1, // The variable identifier (the one given by in IoTize studio)
    converter: NumberConverter.uint32Instance(), // How bytes data should be converted (optional)
  })
  .add('voltage', {
    id: 2,
    converter: NumberConverter.uint32Instance(),
  })
  .add('LEDStatus', {
    id: 3,
    converter: new UniqMaskConverter({
      0x0: 'OFF',
      0x1: 'ON',
      0x2: 'AUTO',
    }),
  });

// You can also configure bundles
tap.bundles.add('Sensors', {
  id: 1, // Bundle id (the one given by IoTize Studio)
  name: 'Sensors',
  variables: [
    {
      id: 1,
      name: 'Temperature',
      converter: NumberConverter.uint16(),
    },
    // ...
  ],
});

IoTizeDevice device = ...;

// Configure your variables
device
    .getTargetVariables()
    .add(VariableConfig.FLOAT(1, "Voltage_V"))
    .add(VariableConfig.UINT(4, "Count"))
    // ...
    ;

// You can also configure bundles
BundleManager bundleManager = device.getTargetBundles();
bundleManager.add(new Bundle(
        1,                      // Bundle ID
        "Sensors",              // Bundle name
        61,                     // Datalogging period
        Arrays.asList(
            VariableConfig.FLOAT(1, "Voltage_V"),           // First variable in bundle
            VariableConfig.FLOAT(2, "Temperature_C")        // Second variable in bundle
        )
));

bundleManager.add(new Bundle(
        1,
        "Count_Status",
        61,
        Arrays.asList(
            VariableConfig.UINT(4, "Count"),
            VariableConfig.ENUM(7, LEDStatusEnum.class, "LEDStatus")
        )
));

With a TapConfigurator instance

You can use TapConfigurator to configure your Tap device.

Configure from an IoTize Studio configuration file

Warning

This is only available with typescript API and this is an experimental feature. We may introduce breaking change in future releases.

import { IotizeConfigFactory } from '@iotize/device-config.js/iotize-config-factory';
import { IotizeConfigModel } from '@iotize/device-config.js/model/iotize-config-model';
import { TapConfigConfigurator } from '@iotize/device-extras.js/configurator';
import { Tap } from '@iotize/device-client.js/device';

let tap: Tap; // ...

// Get the content of the configuration file <serialnumber>.cloud generated by IoTize Studio
// If you are in node.js environment you can use fs.readFileSync
// Otherwise you may need to perform an http request or add a configuration file directly into your app.
let yourConfigFileContent: string =
  '<?xml version="1.0"?><IOTizeConfiguration Version="1.2.0" Lock="8"> ...';
// Parse the config into an IoTizeConfigModel
let configModel: IotizeConfigModel = IotizeConfigFactory.fromXML(
  yourConfigFileContent
);
// Create the TapConfigConfigurator instance with this model.
let tapConfigConfigurator = new TapConfigConfigurator(configModel);
// Apply the configuration to your device object
await tap.configure(tapConfigConfigurator);

// Not documented yet

Read/Write values

Read value

When you read a configuration variable value, this sends a request to the Tap and decodes the output value with the converter you provided during the configuration.

// Get variable object by name
let variable: Variable<number> = device.variables.get('Temperature_C');

let value = await variable.read();
VariableInteraction<Float> variable = device.getTargetVariables().get("Temperature_C");
Float value = variable.read();

Write value

let value = await variable.write(123);
VariableInteraction<Float> variable = device.getTargetVariables().get("Temperature_C");
variable.write(12.3);

Monitoring

Once the variable object is configured, you can easily monitor the values.

Access the monitor object with function Variable::monitor() to get a handle on a VariableMonitor implementation.

You have 3 main functions:

  • start() to start value acquisition
  • pause() to pause value acquisition
  • stop() to stop value acquisition and cleanup allocated resources.

Info

Values are acquired by polling

Start monitoring

For a variable

import { Tap } from '@iotize/device-client.js/device';
import { VariableInteraction } from '@iotize/device-client.js/device/target-variable/variable-interaction.interface';

let tap: Tap; // ... see above

let variable: VariableInteraction<number> = tap.variables.get('temperature_C');
let variableMonitor = variable.monitor();

variableMonitor
  .start({
    forceChange: true, // Update callback is called even if variable has not been modified
    period: 1000, // Checks variable updates every 1000 milliseconds
    duration: -1, // Runs until Monitor::stop() has been called
  })
  .values()
  .subscribe({
    next: (value: number) => {
      // Is emitted every 1000 milliseconds
      console.log(`New value: ${value}`);
    },
  });

// Listen to monitoring events
variableMonitor.events().subscribe((event) => {
  console.log(`Event: `, event);
});

VariableInteraction<Float> variable = device.getTargetVariables().get("Temperature_C");
MonitorEngine<Float> variableMonitor = variable.getMonitor();

variableMonitor.start();

variableMonitor
    .values()
    .subscribe(
        (Float value) => {
            // Is emitted every 1000 milliseconds
            Log.i(TAG, "NEW VALUE => " + value);
        }
    );

Warning

If you want to change the monitoring parameters such as monitoring frequency, you must stop monitoring and then restart with your new parameters.

For a bundle

You can monitor an entire bundle which is faster than monitoring each variable one by one.

import { Tap } from '@iotize/device-client.js/device';
import { Bundle } from '@iotize/device-client.js/device/target-variable/bundle';

let tap: Tap; // ... see above

let bundle: Bundle = tap.bundles.get('<YourBundleId>');
let bundleMonitor = bundle.monitor();
bundleMonitor
  .start({
    forceChange: true, // Update callback is called even if variable has not been modified
    period: 1000, // Checks variable updates every 1000 milliseconds
    duration: -1, // Runs until Monitor::stop() has been called
  })
  .values()
  .subscribe({
    next: (value: Record<string, any>) => {
      // Is emitted every 1000 milliseconds
      console.log(`New values: `, value);
    },
  });

// Listening to monitoring events
bundleMonitor.events().subscribe((event) => {
  console.log(`New event: `, event);
});

// Not documented yet

Pause/Stop monitoring

// You can stop or pause monitoring whenever you want.

// Method 1: Pause monitor
monitor.pause();
// ...
// When paused you can easily restart it
monitor.start();

// Method 2: Stop monitor
// The main difference with Pause is that observable values stream will be complete when Stop is used.
// You have to resubscribe to a new observable value stream to restart monitoring.
monitor.stop();
// You can stop or pause monitoring whenever you want.

// Method 1: Pause monitor
monitor.pause();
// ...
// When paused you can easily restart it
monitor.start();

// Method 2: Stop monitor
// The main difference with Pause is that observable values stream will be complete when Stop is used.
// You have to resubscribe to a new observable value stream to restart monitoring.
monitor.stop();