Skip to content

Target variable

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

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 you device object to work with variable

When you iotize your target application, IoTize Studio give a uniq identifier to your variables. This identifier will be use to access the corresponding resource or your Tap Device.

Tips The identifier of a variable can be found in IoTize Studio: IoTize Explorer / Bundles / <Your bundle> / <Your variable> / Variable Information / Id.

Manually

// We instantiate a device 
let device = IoTizeDevice.create();

// Configure your variables
device
    .variables
    .add("temperature", {
        id: 1, // The variable identifier (the one )
        converter: NumberConverter.uint32instance()
    })
    .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
device
    .bundles
    .add("Sensors", {
        id: 1,
        // Variables must be defined with (see above) otherwise an error will be thrown
        variables: ["temperature", "voltage"]
    });
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,                     // Dataloging 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

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

// get the content of the configuration file <serialnumber>.cloud generated by IoTize Studio
// If you are in node.js environemnt your can use fs.readFileSync 
// Otherwise you may need to perform an http request or add configuration file directly into your app.
let yourConfigFileContent: string = "<?xml version="1.0"?><IOTizeConfiguration Version="1.2.0" Lock="8"> ...";
// Parse the config into a 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 device.configure(configurator);
// Not documented yet 

Read/Write values

Read value

You read a configure variable value. This will send a request to the Tap device and decode the output value with the converter you have 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 you have configured your variable object, you can easily monitor the values.

Access the monitor object with function Variable::monitor(). This will give you an handle on a VariableMonitor implementation.

From there you have 3 main functions - start() to start value acquisition - pause() to pause value acquisition - stop() to stop value acquisition and cleanup allocated resources.

Note: Value acquisition in done by polling

Start monitoring

For a variable

let variable: Variable<number> = device.variables.get("temperature_C");
let variableMonitor = variable.monitor();

variableMonitor
    .start({
        forceRefresh: true, // Update callback will be called even if variable has not been modified
        delay: 1000, // check variable updates every 1000 milliseconds
        duration: -1, // Will run until Monitor::stop() has been called
        // TODO add options old/cold
    })
    .values()
    .subscribe({
        next: (value: number) => {
            // Will be emitted every 1000 milliseconds
            console.log(`New value: ${value}`);
        }
    });

// Listening 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) => {
            // Will be emitted every 1000 milliseconds
            Log.i(TAG, "NEW VALUE => " + value);
        }
    );

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

For a bundle

You can also monitor an entire bundle. It's faster than monitoring each variable one by one.

let bundle: Bundle = device.bundles.get("<YourBundleId>");
let bundleMonitor = bundle.monitor();
bundleMonitor
    .start({
        forceRefresh: true, // Update callback will be called even if variable has not been modified
        delay: 1000, // check variable updates every 1000 milliseconds
        duration: -1, // Will run until Monitor::stop() has been called
        // TODO add options old/cold
    })
    .values()
    .subscribe({
        next: (value: number) => {
            // Will be emitted every 1000 milliseconds
            console.log(`New value: `);
        }
    });

// Listening to monitoring events
bundleMonitor
    .events()
    .subscribe(() => {

    });
// Not documented yet

Pause/Stop monitoring

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

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

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

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

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