Pointer MultiSense Mobile SDK

From Atomation's Wiki
Jump to: navigation, search

Atomation’s mobile SDK is already integrated with the MultiSense wrapping it with a friendly API. The SDK will let you take advantage of all features included in the MultiSense (i.e. Temperature, Humidity, Accelerometer, Magnetometer and Light sensors). All can be easily controlled and the specific functions are up to you.

Getting Atomation's SDK

Register

Visit the Atomation website and click on Download SDK tab.

Login at Atomation

After registration, Login at the Atomation website and reach the Admin. On the Admin Home Page, you will find instructions and guidelines.

Add your Application

Once you have logged in you should start defining your first app:

Name 
Your application's name.
Description 
A brief description of your application.
Package 
The name of the application package (from the top of the Android Manifest file of your App's project).

Adding the SDK and Setting the Token

Add the following line to Module-level /app/build.gradle before dependencies:

repositories {
    jcenter()
}

Add the compile dependency in the build.gradle file:

 compile 'net.atomation.pointer:sdk:1.0.0' 

Add a meta-data element to the application element in the AndroidManifest.xml file:

<application android:label="@string/app_name" ...>
    ...
    <meta-data android:name="net.atomation.Token" android:value="ExamplePointerToken" />
    ...
</application>

The meta-data value (ExamplePointerToken) is Atomation's Token. The Token can be found in the center column in My Applications.

Basics

The MultiSense uses BLE to communicate with the mobile device. To work with this protocol you need to know and understand a few terms:

Central 
The Mobile device, that handles the communication.
Peripheral 
The MultiSense.
MAC Address 
A six byte hex number which represents a physical address of the device, two devices cannot share the same MAC Address.
RSSI 
Received Signal Strength Indicator, how powerful a signal is, measured in Dbm.
Advertise 
A state that the peripheral advertises itself when not connected.
Device Name 
The name advertised by the peripheral.
Write 
The way to send information to the peripheral device.
Read 
The way to get data once (for each read) from the peripheral.
Notifications 
Non stop reads, after enabling it, it is sent automatically from the peripheral.

Crearting Your First Atom

Atoms are the objects that represent MultiSense. While working with Atomation's SDK you need to use three objects:

MultiSenseAtomManager

This objects manages all objects. It creates, saves and retrieves MultiSense Objects.

MultiSenseAtomManager is a Singlton:

    MultiSenseAtomManager manager = MultiSenseAtomManager.getInstance(context);

You can provide any Context object, but it's recommended to provide the Application Context object and not a single component (Activity, Service, etc.).

IMultiSenseAtom

This object represents MultiSense, the data is read from it and written to it.

The way to create it is:

   IMultiSenseAtom atom = manager.getMultiSenseDevice(macAddress);

    if (atom == null) {
        atom = manager.createMultiSenseDevice(macAddress);
    }

The "macAddress" parameter is a String that represents the MAC address of the desired MultiSense in capital letters, separated by colons (for example, "80:30:DC:0C:EA:EC").

ScanHelper

This object is responsible for handling and managing the BLE scan actions. The main goal of scan is to find the advertising peripherals. Due to the MultiSense's transmission policy it is recommended to scan for long periods of time so that the MultiSense's advertise won't be missed.

To use this object you need to:

    ScanHelper scanHelper = ScanHelper.getInstance(context);

Permissions

The SDK adds these permissions to your application:

    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

Android Marshmellow (6.0) Permissions Mechanism

The following permissions are marked as dangerous since Android Marshmellow and must be granted by the user specifically.

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

These permissions are needed in order to initiate a BLE scan, therefore the SDK will request these when the developer starts a scan. If the user does not grant these permissions, the scan will fail and onScanError callback will be called with the USER_NOT_GRANTED_LOCATION_PERMISSIONS error code.

Connectivity

Scanning

The scanning action is performed to see which peripheral devices are around the central. The methods used for scanning and scanning actions can be found in ScanHelper.

startScanning(@NotNull IScanListener listener);
Name Type Description
listener IScanListener A listener that informs on the BLE scan status and the devices found.

When an activated MultiSense (see below) device is found in the scan, the SDK will automatically connect to the MultiSense, read its sensors, send a new configuration to it and disconnect.

Activation

In order to use MultiSense with Atomation's SDK you need to activate the desired MultiSense. To do that you need to use:

    multiSenseAtom.activate(configReadListener, sensorsReadListener);

The activate method requires two Listeners. One of the Listeners is for sensors data from the MultiSense and the other is for the configuration that is sent to the device. The alerts received from the MultiSense are read by the "on...Alert" listeners.

Activating an Atom will start a BLE scan if one isn't currently on. When the activated MultiSense device is found in the scan, the SDK will automatically connect to the MultiSense, read its sensors, send a new configuration to it and disconnect. The current sensor data and configuration data will be received in the listeners described above.

In order to deactivate a MultiSense, use the following:

    multiSenseAtom.deactivate()

Deactivating a MultiSense Atom will stop a BLE scan if there are no active Atoms and the user hasn't initiated a scan directly (using scanHelper.startScanning(...))

Reading Sensor Data

The MultiSense has several sensors. Atomation's SDK can read them in the following way:

Accelerometer

The Accelerometer measures the change in acceleration, the change in acceleration helps measure how much the sensor has moved.

You can read the accelerometer data in one of two ways. The first one is from the SensorsData object returned from sensorReadListener. The data from this listener will update every new connection with the MultiSense:

    float xRead = sensorsData.x;
    float yRead = sensorsData.y;
    float zRead = sensorsData.z;

The second way is used when an alert has happened, from IOnAccelerometerAlert:

To initiate the alert listener you need to use this function from your IMultiSenseAtom object:

setAccelerometerAlertListener(@NotNull IAccelerometerAlertListener listener);
Name Type Description
listener IAccelerometerAlertListener A listener that react to alerts caused by the accelerometer

To stop the alert listener:

removeAccelerometerAlertListener(IAccelerometerAlertListener listener);
Name Type Description
listener IAccelerometerAlertListener A listener that react to alerts caused by the accelerometer

Magnetic

The MultiSense's magnetic sensor is a binary magnetic sensor (only reports on existence / non - existence). It senses the supplied magnet from a distance of 1-3cm.

You can read the magnetic sensor data in one of two ways. The first one is from the SensorsData object returned from sensorReadListener. The data from this listener will update every new connection with the MultiSense:

    boolean magneticRead = sensorsData.magnetState;

Where true is a magnet in proximity and false when not.

The second way is used when an alert has happened, from IMagnetAlertListener:

To initiate the alert listener you need to use this function from your IMultiSenseAtom object:

setMagnetAlertListener(IMagnetAlertListener listener);
Name Type Description
listener IMagnetAlertListener A listener that react to alerts caused by the magnet sensor

To stop the alert listener:

removeMagnetAlertListener(IMagnetAlertListener listener);
Name Type Description
listener IMagnetAlertListener A listener that react to alerts caused by the magnet sensor

Ambient Light

Inside the MultiSense there is an embedded ambient light sensor. The sensor measures the light intensity of the area around the MultiSense. The units returned from the MultiSense are in LUX.

You can read the light sensor data in one of two ways. The first one is from the SensorsData object returned from sensorReadListener. The data from this listener will update every new connection with the MultiSense:

    float lightRead = sensorsData.light;

The minimum value of the sensor is 20lx.

The second way is used when an alert has happened, from ILightAlertListener:

To initiate the alert listener you need to use this function from your IMultiSenseAtom object:

setLightAlertListener(ILightAlertListener listener)
Name Type Description
listener ILightAlertListener A listener that react to alerts caused by the light sensor

To stop the alert listener:

removeLightAlertListener(ILightAlertListener listener)
Name Type Description
listener ILightAlertListener A listener that react to alerts caused by the light sensor

Temperature

One of the MultiSense's capabilities is to read the environmental temperature around it. The MultiSense measures the temperature in Celsius units.

You can read the temperature sensor data in one of two ways. The first one is from the SensorsData object returned from sensorReadListener. The data from this listener will update every new connection with the MultiSense:

    float temperatureRead = sensorsData.temperature;

The second way is used when an alert has happened, from ITemperatureAlertListener:

To initiate the alert listener you need to use this function from your IMultiSenseAtom object:

setTemperatureAlertListener(ITemperatureAlertListener listener)
Name Type Description
listener ITemperatureAlertListener A listener that react to alerts caused by the temperature sensor

To stop the alert listener:

removeTemperatureAlertListener(ITemperatureAlertListener listener)
Name Type Description
listener ITemperatureAlertListener A listener that react to alerts caused by the temperature sensor

Humidity

The MultiSense also measures the humidity percentage around it.

You can read the humidity sensor data in one of two ways. The first one is from the SensorsData object returned from sensorReadListener. The data from this listener will update every new connection with the MultiSense:

    float humidityRead = sensorsData.humidity;

The second way is used when an alert has happened, from IHumidityAlertListener:

To initiate the alert listener you need to use this function from your IMultiSenseAtom object:

setHumidityAlertListener(IHumidityAlertListener listener)
Name Type Description
listener IHumidityAlertListener A listener that react to alerts caused by the humidity sensor

To stop the alert listener:

removeHumidityAlertListener(IHumidityAlertListener listener)
Name Type Description
listener IHumidityAlertListener A listener that react to alerts caused by the humidity sensor

Configuring the MultiSense

The MultiSense's configuration is the settings which include: transmission frequency, alert scheduling and which sensors should be activated.

Activating Sensors

The MultiSense's sensors won't start to read and send sensor data until they are configured. The alerts from each sensor won't work until the specific sensor is enabled. To configure the sensors you need to:

Accelerometer

To enable the accelerometer you need to:

enableAccelerometerSensor(IOnAccelerometerSavedListener listener)
Name Type Description
listener IOnAccelerometerSavedListener A listener that react if the sensor's configuration has been saved or not

To disable the magnetic sensor you need to:

disableAccelerometerSensor(IOnAccelerometerSavedListener listener)
Name Type Description
listener IOnAccelerometerSavedListener A listener that react if the sensor's configuration has been saved or not

Magnetic

To enable the magnetic sensor you need to:

enableMagnetSensor(IOnMagnetSavedListener listener)
Name Type Description
listener IOnMagnetSavedListener A listener that react if the sensor's configuration has been saved or not

To disable the magnetic sensor you need to:

disableMagnetSensor(IOnMagnetSavedListener listener)
Name Type Description
listener IOnMagnetSavedListener A listener that react if the sensor's configuration has been saved or not

Ambient Light

To enable the ambient light sensor you need to:

enableLightSensor(IOnLightSavedListener listener)
Name Type Description
listener IOnLightSavedListener A listener that react if the sensor's configuration has been saved or not

To disable the magnetic sensor you need to:

disableMagnetSensor(IOnLightSavedListener listener)
Name Type Description
listener IOnLightSavedListener A listener that react if the sensor's configuration has been saved or not

Temperature

To enable the temperature sensor you need to:

enableTemperatureSensor(IOnTemperatureSavedListener listener)
Name Type Description
listener IOnTemperatureSavedListener A listener that react if the sensor's configuration has been saved or not

To disable the temperature sensor you need to:

disableTemperatureSensor(IOnTemperatureSavedListener listener)
Name Type Description
listener IOnTemperatureSavedListener A listener that react if the sensor's configuration has been saved or not

Humidity

To enable the humidity sensor you need to:

enableHumiditySensor(IOnHumiditySavedListener listener)
Name Type Description
listener IOnHumiditySavedListener A listener that react if the sensor's configuration has been saved or not

To disable the humidity sensor you need to:

disableMagnetSensor(IOnHumiditySavedListener listener)
Name Type Description
listener IOnHumiditySavedListener A listener that react if the sensor's configuration has been saved or not

Setting Alerts Thresholds

Each sensor other than the magnetic sensor, has a threshold that will determine if an alert will happen or not. Each sensor can be configured separately:

Accelerometer Threshold

Setting the threshold for the accelerometer is done by:

    atom.configureAccelerometerParameters(IMultiSenseAtom.AccelerometerMode.IMPACT, 5.0, accelerometerParameterSavedListener);
configureAccelerometerParameters(@AccelerometerMode int accMode, float threshold, IOnAccelerometerParamsSavedListener listener)
Name Type Description
accMode @AccelerometerMode int An int that configure if the threshold is for Impact or for Free fall
impactThreshold float the value that determine if a read is alert or not. for Free Fall: [0:1]g, for Impact: [0:8]g. resolution is 63mg. meaning that 2 will be rounded up to 2.016
listener IOnAccelerometerParamsSavedListener A listener that reacts to an attempt to save new values. It returns whether or not it was successful.

Light Threshold

Setting the threshold for the light sensor is done by:

    atom.configureLightThreshold(250, lightParameterSavedListener);
configureLightThreshold(int threshold, IOnLightThresholdSavedListener listener)
Name Type Description
threshold int the value that determine if a read is alert or not. range is all even numbers in [0:510]lux
listener IOnLightThresholdSavedListener A listener that reacts to an attempt to save new values. It returns whether or not it was successful.

Temprature Threshold

Setting the thresholds for the temperature sensor is done by:

    atom.configureTemperatureThresholds(0, 25, temperatureParameterSavedListener);
configureTemperatureThresholds(int lowThreshold, int highThreshold, IOnTemperatureThresholdsSavedListener listener)
Name Type Description
lowThreshold int The value that determine if a read is alert or not, if the temperature falls below this an alert will be sent. Range: [-40:80]°C
highThreshold int The value that determine if a read is alert or not, if the temperature rises higher than this an alert will be sent. Range: [-40:80]°C
listener IOnTemperatureThresholdsSavedListener A listener that reacts to an attempt to save new values. It returns whether or not it was successful.

Humidity Threshold

Setting the thresholds for the humidity sensor is done by:

    atom.configureHumidityThresholds(40, 80, humidityParameterSavedListener);
configureHumidityThresholds(int lowThreshold, int highThreshold, IOnHumidityThresholdsSavedListener)
Name Type Description
lowThreshold int The value that determine if a read is alert or not, if the humidity percentage falls below this an alert will be sent. Range: [0:100]%
highThreshold int The value that determine if a read is alert or not, if the humidity percentage rises higher than this an alert will be sent. Range: [0:100]%
listener IOnHumidityThresholdsSavedListener A listener that reacts to an attempt to save new values. It returns whether or not it was successful.

Setting Timers

MultiSense has four configurable timers, each timer will determine the MultiSense's advertise time in different states. The first three timers affect the Temperature and Humidity sampling.

in Addition there are other asynchronous events which will cause the MultiSense to wake:

  • Pressing the button
  • Impact or Free-fall event generated by the Accelerometer
  • Sensing a change in the magnetic field
  • crossing the light threshold to either direction

To configure the timers you need to:

Relaxed Timer

The Relaxed Timer is used when the temperature and humidity are within their limits. Meaning that if, for example, the temperature limits were configure to [0:20]°C. as long as the measured temperature (when the MultiSense wakes for any reason and samples the sensors) is within this range, the next temperature sampling will be after the number of seconds configured in the relaxed timer has passed.

Important Note: remember that the MultiSense sleeps most of the time. even if the temperature of the MultiSense exceeds the limits defined, as long as it didn't happen when it was awake and sampling, it didn't happen (!) and the MultiSense will continue sleeping. Same goes for humidity.

To configure the relaxed timer, you need to:

    atom.setRelaxedTimer(60, relacxedTimerSavedListener);
setRelaxedTimer(int relaxedTimerSeconds, IOnRelaxedTimerSavedListener listener)
Name Type Description
relaxedTimerSeconds int The time in seconds between two transmissions caused by this timer. Range: all the even numbers in [2:86400]sec (up to 24h)
listener IOnRelaxedTimerSavedListener A listener that reacts to a change in timer configuration. Returns whether or not the save was successful.

Proximity Timer

This timer is used all the time independently from the other timers.

To configure the proximity timer, you need to:

    atom.setProximityTimer(60, proximityTimerSavedListener);
setProximityTimer(int proximityTimerSeconds, IOnProximityTimerSavedListener listener)
Name Type Description
proximityTimerSeconds int The time in seconds between two transmissions caused by this timer. Range: all the even numbers in [2:86400]sec (up to 24h)
listener IOnProximityTimerSavedListener A listener that reacts to a change in timer configuration. Returns whether or not the save was successful.

Violation Timer

This timer is used when the temperature and humidity are out of the configured limits. This is the counterpart for the relaxed timer and the same applies to it. see Relaxed Timer above. To configure the violation timer, you need to:

    atom.setViolationTimer(60, violationTimerSavedListener);
setViolationTimer(int violationTimerSeconds, IOnViolationTimerSavedListener listener)
Name Type Description
violationTimerSeconds int The time in seconds between two transmissions caused by this timer. Range: all the even numbers in [2:86400]sec (up to 24h)
listener IOnViolationTimerSavedListener A listener that reacts to a change in timer configuration. Returns whether or not the save was successful.

Alert Timer

This timer defines the timeout before alert generation after a limit is crossed To configure the alert timer, you need to:

    atom.setAlertTimer(60, alertTimerSavedListener);
setAlertTimer(int alertTimerSeconds, IOnAlertTimerSavedListener listener)
Name Type Description
alertTimerSeconds int The time in seconds between two transmissions caused by this timer. Range: [1:255]min
listener IOnAlertTimerSavedListener A listener that reacts to a change in timer configuration. Returns whether or not the save was successful.

General Properties

Other than sensors and timers the MultiSense has a few more features:

Working Modes

The MultiSense has three working modes:

    atom.setOperationMode(@OperationalMode int mode)

Modes can be found in IMultiSenseAtom.OperationalMode

Normal

In Normal mode you can edit the configuration and read the sensor data. The sensor data and configuration will be uploaded automatically to the database.

Guest

In Guest mode you can only read the sensor data. The sensor data will be uploaded automatically to the database.

Tag

In Tag mode you cannot edit the configuration or read the sensors data. Instead, the data from the MultiSense device will be uploaded directly to the database without revealing it to the user.

Button Press

Pressing the MultiSense button initiates an advertise. Atomation's SDK enables you to know when this press has happened:

Setting the listener:

setButtonPressedListener(IOnButtonPressedListener listener)
Name Type Description
listener IOnButtonPressedListener A listener that react if the the button has been pressed

Removing the listener:

removeButtonPressedListener(IOnButtonPressedListener listener)
Name Type Description
listener IOnButtonPressedListener A listener that react if the the button has been pressed

DeadBattery

If the MultiSense shuts down due to lack of battery it will be transmitted. With the SDK you can catch the event:

Setting the dead battery listener:

setDeadBatteryAlertListener(IDeadBatteryAlertListener listener)
Name Type Description
listener IDeadBatteryAlertListener A listener that react to the power end of a MultiSense

Removing the listener:

setDeadBatteryAlertListener(IDeadBatteryAlertListener listener)
Name Type Description
listener IDeadBatteryAlertListener A listener that react to the power end of a MultiSense

Package State

The MultiSense can detect its package state. To read it you need to:

Setting the package listener:

setPackageStateAlertListener(IPackageStateChangedAlertListener listener)
Name Type Description
listener IPackageStateChangedAlertListener A listener that react to the package state change

Removing the listener:

setDeadBatteryAlertListener(IDeadBatteryAlertListener listener)
Name Type Description
listener IPackageStateChangedAlertListener A listener that react to the package state change

Writing Data to the Database

Every read, alert and configuration action is automatically uploaded to the database. If you want to upload any other data you can do it using the sendEvent method from the IMultiSenseAtom object. Send event method:

sendEvent(String event, String type, String data)
Name Type Description
event String A String that will be sent to the Data Base, it is recommended to send the kind of event (for example, TempratureAlert).
type String A String that will be sent to the Data Base, it is recommended to send the a description of what happened (for example, HighTemp).
data String A String that will be sent to the Data Base, it is recommended to send the actual numbers (for example, 60).

Sample Code

The sample code is a helpful reference that will simplify your development process. Find the source code for a working app built on the SDK here.

When registering you will receive an example application, under Sample Code in the left main menu. You need to copy its Token to your example app in order for it to compile. Paste it in the manifest file:

<application android:label="@string/app_name" ...>
    ...
    <meta-data android:name="net.atomation.Token" android:value="ExamplePointerToken" />
    ...
</application>

The meta-data value (ExamplePointerToken) is Atomation's Token. The Token can be found on the center column in My Applications.

Reports

Atomation's report system will let you explore the data with a friendly interface. The data is divided to different parameters on a timeline and can be exported to third party formats (including Excel, XML, JSON and more). Reports can be found in My Applications.