iobeam is a data platform for connected devices.
This is a Java library for sending data to iobeam, e.g., from within an Android app. For more information on iobeam, please read our full API documentation.
Please note that we are currently invite-only. You will need an invite to generate a valid token and use our APIs. (Sign up here for an invite.)
We've written a couple sample Android apps to illustrate how to use this library:
-
Android Battery Data App - Basic example that tracks the current battery level on your phone. Every time the battery level changes by more than 1%, the app uploads the timestamp and current level to iobeam.
-
Android WiFi RSSI App - Slightly more advanced example that uses Callbacks. Measures the signal strength of the WiFi on your phone using RSSI (received signal strength indicator). Measurements are taken every 20 seconds, and are uploaded to iobeam in batches of 3 or more measurements.
Before you can start sending data to iobeam, you'll need a project_id
and
project_token
(with write-access enabled) for a valid iobeam account.
You can get these easily with our
Command-line interface tool.
To install to your local Maven repository:
git clone https://github.com/iobeam/iobeam-client-java.git
cd iobeam-client-java
mvn install
It will be installed as artifact iobeam-client-java
under the group com.iobeam
.
If you are building an Android app, add the following lines to your app/build.gradle
file:
repositories {
...
mavenLocal()
mavenCentral()
}
dependencies {
...
compile('com.iobeam:iobeam-client-java:0.6.1') {
exclude module: 'json'
}
}
It is also available on Maven Central.
This library allows Java clients to send data to iobeam.
At a high-level, here's how it works:
-
Initialize an
Iobeam
object with yourproject_id
andproject_token
-
Register your device to get an auto-generated
device_id
. Optionally, you can initialize the object with adevice_id
in the previous step and skip this step -
Create a
DataStore
for storing data by streams, which will be tracked by theIobeam
object. -
Add data values to the
DataStore
as you get them. -
When you're ready, send your data to iobeam.
Here's how to get started, using a basic example that sends temperature data to iobeam.
(For simplicity, let's assume that the current temperature can be accessed
with getTemperature()
).
(Reminder: Before you start, create a user account, project, and project_token (with write access)
using the iobeam APIs or Command-line interface. Write down your new project_id
and project_token
.)
There are several ways to initialize the Iobeam
library. All require that you have project_id
and project_token
before hand.
Without a registered device_id
If you have not previously registered a device_id
with iobeam, either via the CLI or our website,
you will need to register one in code. There are two ways to register a device_id
:
(1) Let iobeam generate one for you:
Iobeam iobeam = new Iobeam.Builder(PROJECT_ID, PROJECT_TOKEN).saveIdToPath(PATH).build();
iobeam.registerDeviceAsync();
(2) Provide your own (must be unique to your project):
Iobeam iobeam = new Iobeam.Builder(PROJECT_ID, PROJECT_TOKEN).saveIdToPath(PATH).build();
iobeam.registerDeviceAsync("my_desired_device_id");
The device_id
will be saved to disk at the path PATH
. On Android, this would be set to something
like this.getFilesDir().getAbsolutePath()
, which is internal storage for applications. On future
calls, this on-disk storage will be read first. If a device_id
exists, the
registerDeviceAsync()
will do nothing; otherwise, it will get a new random ID from us. If you
provide a different device_id
to registerDeviceWithIdAsync()
, the old one will be replaced.
With a registered device_id
If you have registered a device_id
(e.g. using our CLI),
you can pass this in the constructor and skip the registration step.
Iobeam iobeam = new Iobeam.Builder(PROJECT_ID, PROJECT_TOKEN).saveIdToPath(PATH)
.setDeviceId(DEVICE_ID).build();
You must have registered some other way (CLI, website, previous installation, etc) for this to work.
Advanced: not saving to disk
If you don't want the device_id
to be automatically stored for you, set the path
parameter in
either constructor to be null
:
// Without registered id:
Iobeam iobeam = new Iobeam.Builder(PROJECT_ID, PROJECT_TOKEN).build();
// With registered id:
Iobeam iobeam = new Iobeam.Builder(PROJECT_ID, PROJECT_TOKEN)
.setDeviceId(DEVICE_ID).build();
This is useful for cases where you want to persist the ID yourself (e.g. in a settings file), or if
you are making Iobeam
objects that are temporary. For example, if the device you are using acts
as a relay or proxy for other devices, it could get the device_id
from those devices and have
no need to save it.
To track time-series data, you need to decide how to break down your data
streams into "stores", a collection of data streams grouped together. You
create a DataStore
with a list of stream names that the store contains.
So if you're tracking just temperature in a store:
DataStore store = iobeam.createDataStore(new String[]{"temperature"});
By doing this, the iobeam client now knows about your DataStore
(it is "tracking" it), and
each subsequent call to send data will include any new data from this DataStore
.
So, for every data point, you'll want to add it to the store with a timestamp
when the measurement occurred:
long timestamp = System.currentTimeMillis();
store.add(timestamp, new String[]{"temperature"}, new Object[]{getTemperature()});
// Or, to just use the current timestamp:
store.add(new String[]{"temperature"}, new Object[]{getTemperature()});
You pass in the values keyed by which column they belong to. In the above format
you do that by providing an array of column names and an equal size Object
array
of corresponding values. You can create a Map
that maps columns/streams to
values:
Map<String, Object> values = new HashMap<String, Object>();
values.put("temperature", getTemperature());
store.add(values);
Note that the DataStore
object can hold several streams at once. For
example, if you also had a getHumidity()
function, you could track both in
the same DataStore
:
String[] columns = new String[]{"temperature", "humidity"};
DataStore store = iobeam.createDataStore(columns);
Object[] values = new Object[2];
values[0] = getTemperature();
values[1] = getHumidity();
store.add(columns, values);
Not every add()
call needs all streams to have a value; if a stream is omitted
from both arrays (or from the keys of a Map
), it will be assumed to be null
.
You can send your data to iobeam in two ways: synchronously and asynchronously:
iobeam.send(); // blocking
iobeam.sendAsync(); // non-blocking
If there are problems with the data as provided to either register()
or send()
(and their
async variants), an ApiException
is thrown. These problems include unrecoverable issues like
incorrect project ID or device ID, invalid data,
etc. IOException
is thrown in the case of network connectivity issues. As a user of the library,
you should be aware of these errors and handle them appropriately (e.g. catching them, logging,
etc.).
Here's the full source code for our example:
// Initialization
Iobeam iobeam = new Iobeam.Builder(PROJECT_ID, PROJECT_TOKEN)
.saveIdToPath(PATH)
.build();
if (iobeam.getDeviceId() == null) {
iobeam.registerDeviceAsync(); // Registers using auto-generated device_id
}
...
// Data gathering
String[] columns = new String[]{"temperature", "humidity"};
DataStore store = iobeam.createDataStore(columns);
Object[] values = new Object[2];
values[0] = getTemperature();
values[1] = getHumidity();
store.add(columns, values);
...
// Data transmission
iobeam.sendAsync();
These instructions should hopefully be enough to get you started with the library!