See: Description
Package | Description |
---|---|
oracle.iot.client |
Client API for the Oracle IoT Cloud Service.
|
oracle.iot.client.device |
API for directly–connected devices and gateway devices as clients
of the Oracle IoT Cloud Service.
|
oracle.iot.client.enterprise |
APIs for an enterprise client of the Oracle IoT Cloud Service.
|
The configuration is created by running the "bin/provisioner.sh" or "bin/provisioner.bat" tool which is part of the client library binary distribution. This tool creates an encrypted file that is used when running the client application. Running provisioner.sh or provisioner.bat with a -h option will provide usage.
The client library has explicit API for obtaining a device model. See oracle.iot.client.Client#getDeviceModel(java.lang.String).
By default the API above always uses the network to retrieve a given device
model. This behavior can be changed to cache device models to a local file
store by setting the property oracle.iot.client.device_model_store
to an existing, local file directory. Each model will be stored in its own file
using a pattern of "dm-{URL encoded device model URN}.json"
, for
example
"dm-urn%3Acom%3Aoracle%3Aiot%3Adevice%3Ahumidity_sensor.json"
.
Statically provisioning a local file directory with device models avoids
network traffic; however, the local model must be identical to the model on the
server. Dynamic provisioning, in which the client library retrieves the model
from the server, ensures correctness of the model, but at the expense of
network traffic. Dynamic provisioning is recommended.
Beware that when using a local store of device models, a local model will not get updated if the model on the server is changed.
Both enterprise and device clients share common API for getting and setting
values through a user-interface (in the case of an enterprise client application)
and for getting and setting values on a physical device (in the case of a
device client application). A device client application will create
an oracle.iot.client.DirectlyConnectedDevice
or an
oracle.iot.client.GatewayDevice
. An enterprise client
application will create an oracle.iot.client.EnterpriseClient
.
From there, the application can use the Oracle IoT Client API to create instances of
a "virtual device" which provides access to get and set
values. Further detail is available in the oracle.iot.client.Client
javadoc.
1. Initialize device client, ensure that the configurationFilePath is not pointing to a read only file as this might be modified during activation
oracle.iot.client.DirectlyConnectedDevice dcd =
new oracle.iot.client.DirectlyConnectedDevice(configurationFilePath, password);
2. Activate the device
if (!dcd.isActivated()) {
dcd.activate(deviceModelUrn);
}
3. Obtain the device model
DeviceModel deviceModel = dcd.getDeviceModel(deviceModelUrn):
4. Create a virtual device implementing the device model
oracle.iot.client.device.VirtualDevice virtualDevice =
dcd.createVirtualDevice(dcd.getEndpointId(), deviceModel);
5. Listen for control operations from an enterprise client
// set a callback for any changes from the server to this virtual object
virtualDevice.setOnChange(new oracle.iot.client.device.VirtualDevice.ChangeCallback<oracle.iot.client.device.VirtualDevice>() {
public void onChange(oracle.iot.client.device.VirtualDevice.ChangeEvent<oracle.iot.client.device.VirtualDevice> event) {
oracle.iot.client.device.VirtualDevice virtualDevice = event.getVirtualDevice();
oracle.iot.client.device.VirtualDevice.NamedValue<?> namedValue = event.getNamedValue();
while (namedValue != null) {
String attribute = namedValue.getName();
Object value = namedValue.getValue();
// update the device with the new value
namedValue = namedValue.next();
}
}
});
// Set a handler for a callable action. For example, the device model
// might have a 'reset' action. In this example, the action does not
// require any input data.
virtualDevice.setCallable("reset", new oracle.iot.client.device.VirtualDevice.Callable<Void>() {
public void call(oracle.iot.client.device.VirtualDevice virtualDevice, Void not_used) {
// reset the device
}
});
// Set a handler for a callable action. For example, the device model
// might have a 'calibrate' action. In this example, the action
// requires numeric input data.
virtualDevice.setCallable("calibrate", new oracle.iot.client.device.VirtualDevice.Callable<Number>() {
public void call(oracle.iot.client.device.VirtualDevice virtualDevice, Number zeroOffset) {
// calibrate the device to zeroOffset
}
});
// set a callback to receive errors from sending data to the server
virtualDevice.setOnError(new oracle.iot.client.device.VirtualDevice.ErrorCallback<oracle.iot.client.device.VirtualDevice>() {
public void onError(oracle.iot.client.device.VirtualDevice.ErrorEvent<oracle.iot.client.device.VirtualDevice> event) {
oracle.iot.client.device.VirtualDevice device = event.getVirtualDevice();
String message = event.getMessage();
oracle.iot.client.device.VirtualDevice.NamedValue<?> namedValue = event.getNamedValue();
// get the attributes that are affected by the error
while (namedValue != null) {
String attribute = namedValue.getName();
Object value = namedValue.getValue();
// log or otherwise handle the error
namedValue = namedValue.next();
}
}
});
6. Update the virtual device when the data on the physical device changes
// set a value for a particular attribute in this virtual device
oracle.iot.client.device.VirtualDevice.set("attribute", newValue);
// or set multiple attributes in a batch operation
virtualDevice.update()
.set("attribute1", value1)
.set("attribute2", value2)
.finish();
7. Dispose of the device client
dcd.close();
1. Initialize gateway device client, ensure that the configurationFilePath is not pointing to a read only file as this might be modified during activation
oracle.iot.client.GatewayDevice gw =
new oracle.iot.client.GatewayDevice(configurationFilePath, password);
2. Activate the gateway device
if (!gw.isActivated()) {
gw.activate();
}
3. Obtain the device model
DeviceModel deviceModel = gw.getDeviceModel(deviceModelUrn):
4. Register indirectly-connected devices
// create meta-data with the indirectly-connected device's
// manufacturer, model, and serial number
Map<String,String> metaData = new HashMap<String, String>();
metaData.put(oracle.iot.client.GatewayDevice.MANUFACTURER, "A Manufacturer");
metaData.put(oracle.iot.client.GatewayDevice.MODEL_NUMBER, "MN-xxxx-xxxx");
metaData.put(oracle.iot.client.GatewayDevice.SERIAL_NUMBER, "SN-yyyyyyyy");
// add any vendor-specific meta-data to the metaData Map
// register it
String deviceId = gw.registerDevice(hardwareId, metaData, deviceModelUrn);
5. Create a virtual device implementing the device model
oracle.iot.client.device.VirtualDevice virtualDevice = gw.createVirtualDevice(deviceId, deviceModel);
6. Listen for control operations from enterprise client
// set a callback for any changes from the server to this virtual object
virtualDevice.setOnChange(new oracle.iot.client.device.VirtualDevice.ChangeCallback<oracle.iot.client.device.VirtualDevice>() {
public void onChange(oracle.iot.client.device.VirtualDevice.ChangeEvent<oracle.iot.client.device.VirtualDevice> event) {
oracle.iot.client.device.VirtualDevice virtualDevice = event.getVirtualDevice();
oracle.iot.client.device.VirtualDevice.NamedValue<?> namedValue = event.getNamedValue();
while (namedValue != null) {
String attribute = namedValue.getName();
Object value = namedValue.getValue();
// update the device with the new value
namedValue = namedValue.next();
}
}
});
// Set a handler for a callable action. For example, the device model
// might have a 'reset' action. In this example, the action does not
// require any input data.
virtualDevice.setCallable("reset", new oracle.iot.client.device.VirtualDevice.Callable<Void>() {
public void call(oracle.iot.client.device.VirtualDevice virtualDevice, Void not_used) {
// reset the device
}
});
// Set a handler for a callable action. For example, the device model
// might have a 'calibrate' action. In this example, the action
// requires numeric input data.
virtualDevice.setCallable("calibrate", new oracle.iot.client.device.VirtualDevice.Callable<Number>() {
public void call(oracle.iot.client.device.VirtualDevice virtualDevice, Number zeroOffset) {
// calibrate the device to zeroOffset
}
});
virtualDevice.setOnError(new oracle.iot.client.device.VirtualDevice.ErrorCallback<oracle.iot.client.device.VirtualDevice>() {
public void onError(oracle.iot.client.device.VirtualDevice.ErrorEvent<oracle.iot.client.device.VirtualDevice> event) {
oracle.iot.client.device.VirtualDevice device = event.getVirtualDevice();
String message = event.getMessage();
oracle.iot.client.device.VirtualDevice.NamedValue<?> namedValue = event.getNamedValue();
// get the attributes that are affected by the error
while (namedValue != null) {
String attribute = namedValue.getName();
Object value = namedValue.getValue();
// log or otherwise handle the error
namedValue = namedValue.next();
}
}
});
7. Update the virtual device when the data on the physical device changes
// set a value for a particular attribute in this virtual device
virtualDevice.set("attribute", newValue);
// or set multiple attributes in a batch operation
virtualDevice.update()
.set("attribute1", value1)
.set("attribute2", value2)
.finish();
8. Dispose of the virtual device
virtualDevice.close()
9. Dispose of the gateway device client
gw.close();
1. Initialize enterprise client,ensure that the configurationFilePath is not pointing to a read only file as this might be modified during activation
EnterpriseClient ec =
EnterpriseClient.newClient(configurationFilePath, password);
2. If the device model of the target device is not known at application startup,
it can be selected from a list
// To enumerate device models available in this app
Pageable<String> deviceModelUrns = ec.getDeviceModels();
while (deviceModelUrns.hasMore()) {
deviceModelUrns.next();
Collection<String> urns = deviceModelNames.elements();
... application or user selects a model URN ...
}
3. If the endpoint ID of the target device is not known at application start up,
it can be selected from a list of active devices implementing a given device model
// To enumerate devices implementing this device model
Pageable<Device> devices = ec.getActiveDevices(deviceModelUrn);
while(devices.hasMore()) {
Collection<Device> names = devices.elements();
... application or user selects a device ...
}
4. Create a virtual device for the target device and model
DeviceModel deviceModel = ec.getDeviceModel(deviceModelUrn);
oracle.iot.client.enterprise.VirtualDevice virtualDevice =
ec.createVirtualDevice(device.getId(), deviceModel);
5. Monitor the device
// set a callback for any changes to this virtual object
virtualDevice.setOnChange(new oracle.iot.client.enterprise.VirtualDevice.ChangeCallback<oracle.iot.client.enterprise.VirtualDevice>() {
public void onChange(oracle.iot.client.enterprise.VirtualDevice.ChangeEvent<oracle.iot.client.enterprise.VirtualDevice> event) {
oracle.iot.client.enterprise.VirtualDevice virtualDevice = event.getVirtualDevice();
oracle.iot.client.enterprise.VirtualDevice.NamedValue<?> namedValue = event.getNamedValue();
while (namedValue != null) {
String attribute = namedValue.getName();
Object value = namedValue.getValue();
// Perform application behaviors based on attribute changes
namedValue = namedValue.next();
}
}
});
virtualDevice.setOnError(new oracle.iot.client.enterprise.VirtualDevice.ErrorCallback<oracle.iot.client.enterprise.VirtualDevice>() {
public void onError(oracle.iot.client.enterprise.VirtualDevice.ErrorEvent<oracle.iot.client.enterprise.VirtualDevice> event) {
oracle.iot.client.enterprise.VirtualDevice device = event.getVirtualDevice();
String message = event.getMessage();
oracle.iot.client.enterprise.VirtualDevice.NamedValue<?> namedValue = event.getNamedValue();
// get the attributes that are affected by the error
while (namedValue != null) {
String attribute = namedValue.getName();
Object value = namedValue.getValue();
// Perform error handling on device errors.
namedValue = namedValue.next();
}
}
});
6. Control the device
// set a value for a particular attribute in this virtualDevice
virtualDevice.set("attribute ", newValue);
// or set multiple attributes in a batch operation
virtualDevice.update()
.set("attribute1", value1)
.set("attribute2", value2)
.finish();
// execute an action with data, for example 'calibrate', on the virtualDevice
virtualDevice.call("calibrate", value);
// execute an action without data, for example 'reset', on the virtualDevice
virtualDevice.call("reset");
7. Dispose of the enterprise client
ec.close();
This example shows the typical use case from a DirectlyConnectedDevice. But the code for a GatewayDevice or EnterpriseClient is the same.
StorageObject storageObject = directlyConnectedDevice.createStorageObject("mediaSnapshot.jpg", "image/jpg");
storageObject.setInputPath("../images/mediaSnapshot.jpg");
virtualDevice.set("snapshot", storageObject);
A StorageObject may also be set on an Alert field, or as an Action parameter,
provided the type in the device model is URI.
This example shows the typical use case from an onChange event. The code for an onAlert or for an action callback is much the same.
virtualDevice.setOnChange("snapshot", new VirtualDevice.ChangeCallback<VirtualDevice>() {
public void onChange(AbstractVirtualDevice.ChangeEvent<VirtualDevice> event) {
VirtualDevice.NamedValue namedValue = event.getNamedValue();
StorageObject storageObject = (StorageObject) namedValue.getValue();
// only download if image is less than 4M
if (storageObject.getLength() < 4 * 1024L * 1024L) {
try {
storageObject.setOutputPath("../downloads/"+storageObject.getName());
storageObject.sync();
} catch (FileNotFoundException e) {
System.err.println("cannot create file for download");
}
}
}
});
For the upload case, set the SyncCallback on the storage object before setting the virtual device attribute. For the download case, set the SyncCallback on the storage object from within the onChange callback.
storageObject.setOnSync(new StorageObject.SyncCallback<VirtualDevice>() {
public void onSync(StorageObject.SyncEvent<VirtualDevice> event) {
StorageObject storageObject = event.getStorageObject();
if (storageObject.getSyncStatus() == StorageObject.SyncStatus.IN_SYNC) {
// image was uploaded and can be deleted
} else if (storageObject.getSyncStatus() == StorageObject.SyncStatus.SYNC_FAILED) {
// image was not uploaded, take action!
}
}
});
Key | Meaning |
---|---|
oracle.iot.client.device.dispatcher_polling_interval |
Default: 3 seconds The polling interval, in seconds, for message dispatching. If a message is not sent to the server within this timeout, an empty message will be sent in order to solicit request messages that may be queued in the server. |
oracle.iot.client.device.message_dispatcher_base_number_of_retries
|
Default: 3 Controls the number of times a message is retried if the message cannot be sent. A message with a reliability of no-guarantee is retried this number of times. A message with a reliability of best-effort is retried twice this number of times. A message with a reliability of guaranteed-delivery is retried an unlimited number of times. The value must be greater than zero. |
oracle.iot.client.device.message_dispatcher_backoff
|
Default: 1000 milliseconds Amount of time in milliseconds to backoff if the client receives an HTTP 503 response from the server. This is the initial value used for the amount of time to backoff. The backoff time increases exponentially if the server continues to return an HTTP 503 response. |
oracle.iot.client.device.message_dispatcher_reliability
|
Default: BEST_EFFORT Default reliability for messages. NO_GUARANTEE: Message will not be persisted, number of retries if sending was unsuccessful is the base number of retries. BEST_EFFORT: Message will be persisted, number of retries if sending was unsuccessful is two times the base number of retries. GUARANTEED_DELIVERY: Message will be persisted, number of retries is unlimited. |
oracle.iot.client.device.dispatcher_max_queue_size |
Default: 10000 Total messages to queue. Attempts to send messages when the queue is full will result in an error. |
oracle.iot.client.device.dispatcher_max_messages_per_connection |
Default: 100 Maximum number of outgoing messages to send in one payload per HTTPS connection to the server. |
oracle.iot.client.device.request_buffer_size |
Default: 4192 bytes The size, in bytes, of the buffer for holding incoming messages received from the server pending dispatch to handlers in the application. |
com.oracle.iot.client.disable_long_polling |
Default: false Long polling is used by default, set this to true to disable it. |
com.oracle.iot.client.long_polling_timeout_offset |
Default: 100 milliseconds The time, in milliseconds, added to the receive timeout given by the application and then used for the client transport timeout. |
oracle.iot.client.device.send_receive_timeout |
Default: 100 milliseconds Only used when long polling is disabled. The minimum time, in milliseconds, since the last send before polling the server for incoming messages if the receive buffer is empty. A larger value may cause a delay in the receipt of incoming messages, but will cause less network overhead. A value of zero will cause the library to skip the poll for incoming messages when calling receive if the receive buffer is empty. |
oracle.iot.client.enterprise.monitor_max_formats
|
Default: 10 The number of alerts each request the enterprise client performs for virtual device updates can have. |
oracle.iot.client.enterprise.message_enumerator_limit |
Default: 10 The number of messages to return in the Pageable<Message>
from the MessageEnumerator getMessages API.
The value will be clamped between 10 and 200, inclusive. |
com.oracle.iot.client.enterprise.message_polling_interval |
Default: 3000 milliseconds The amount of delay, in milliseconds, between polls for messages by the MessagePoller. This setting affects how often a MessageEnumerator.MessageListener instance may be called. |
com.oracle.iot.client.enterprise.message_polling_limit |
Default: 10 The maximum number of messages to return on a single poll by the MessagePoller. The value will be clamped between 10 and 200, inclusive. |
oracle.iot.client.http_response_timeout |
Default: 15000 milliseconds Only used when long polling is disabled. The amount of time, in milliseconds, to wait for the server to respond to an HTTPS request. |
oracle.iot.client.tam |
Default: null The fully qualified name of a class implementing com.oracle.iot.client.trust.TrustedAssetsManager. The specified class must have a public constructor accepting an Object parameter.
See Trusted Assets for more
information. |
oracle.iot.client.device_model_store |
Default: null If the property is not set, device models will not be stored locally. An existing, local file directory where statically provisioned device models are stored. See Device Models for more information. |
com.oracle.iot.client.device.allow_draft_device_models |
Default: false The server will create a draft device model for device models that have not been provisioned on the server. When set to false, this flag overrides that behavior. The consequence of setting the flag to false is that API that takes a device model URN may throw an exception if the device model has not been provisioned. If the flag is set to true, however, a coding error might go unnoticed. This flag also controls whether or not the client will accept a draft device model from the server. |
oracle.iot.client.pretty_print_messages |
Default: true Controls whether or not logged messages should be pretty printed. Pretty printing the messages makes the JSON easier to read. By default, pretty printing is enabled. Set this property to false to disable pretty printing for a more compact view of the logged messages. |
oracle.iot.client.network_cost |
Default: ETHERNET Used by the "batchByCost" device function, set this property to the type of connected network. The property may be set from the application code; for example, when the type of connected network changes. |
oracle.iot.client.configuration_path |
Default: current directory The directory where the simple trusted assets manager will store activation parameters. |
oracle.iot.client.disable_storage_object_prefix
|
Default: false Disable the prefixing the storage object's name with the device's client ID and a directory separator. |
oracle.iot.client.device.request_dispatcher_thread_pool_size
|
Default: 1 Number of threads created for dispatching request messages so that request handlers can be executed in parallel. This number should be specified as greater than one, else it will be ignored and the default value of one will be used for request handler thread pool size. |
com.oracle.iot.client.device.persistence_directory |
Default: System property user.dir The directory that is used for local persistence. |
com.oracle.iot.client.device.persistence_db_name |
Default: persistence_store The name of the database used for persisting data. |
com.oracle.iot.client.device.persistence_enabled |
Default: true If true, the client library will persist data. |
com.oracle.iot.client.device.isolation_level |
Default: java.sql.Connection.TRANSACTION_READ_UNCOMMITTED Get the transaction isolation level for SQL database persistence. |