Directly Connected Device Client Quick Start

The following steps must be performed by a device client application to allow a device to be monitored and controlled.

  • Initialize device client
var dcd: DirectlyConnectedDevice =
    try DirectlyConnectedDevice()
  • Activate the device
if !dcd.isActivated() {
    try dcd.activate(deviceModels: HUMIDITY_SENSOR_MODEL_URN),
        callback: { (endpointId, error) in
        // ... get device model, create virtual device etc - see below
    })
} 
  • Create a virtual device implementing the device model
var virtualDevice: VirtualDevice
try dcd.getDeviceModel(HUMIDIY_SENSOR_MODEL_URN, 
    callback: { deviceModel, error in
        if let returnObject = deviceModel {
            do {   
                virtualDevice = 
                    dcd.createVirtualDevice(dcd.getEndpointId(),
                        deviceModel: returnObject)
                // do messaging (see below)
            } catch {
                // error handling
            }
        }
    })
  • Listen for control operations from an enterprise client using a closure
virtualDevice.setOnChange({ event in
    var device: VirtualDevice = event.getVirtualDevice()
    // update the device with the new value
    var namedValue: NamedValue = event.getNamedValue()
    var attribute: String = namedValue.getName()
    var value: AnyObject = namedValue.getValue()
    // check namedValue.next() to see if there are
    // more values in the chain
    // ...
})

virtualDevice.setOnError({ event in
    var device: VirtualDevice = event.getVirtualDevice()
    // log error here
})
  • Update the virtual device when the data on the physical device changes
// set a value for a particular attribute in the virtual device
try virtualDevice.set(HUMIDITY_ATTRIBUTE, withId: newValue)
  • Dispose of the device client
dcd.close()

Gateway Device Client Quick Start

The following steps must be performed by a gateway device client application to allow indirectly connected devices to be monitored and controlled.

  • Initialize gateway device client
var gd: GatewayDevice = try GatewayDevice(path, password)
  • Activate the gateway device
if !gd.isActivated() {
    // Provide a callback to obtain the endpointId and register devices
    // within that callback.
    gd.activate(deviceModels: HUMIDITY_SENSOR_MODEL_URN, 
                              TEMPERATURE_SENSOR_MODEL_URN,
        callback: { (endpointId, error) in
            // get device model, create virtual device, 
            // register ICDs etc - see below
        })
}
  • Register indirectly-connected devices
// create meta-data with the indirectly-connected device's
// manufacturer, model, and serial number
var metaData: [String : String] = [ : ]
metaData[CLCT.MANUFACTURER] = ...
metaData[CLCT.MODEL_NUMBER] = ...
metaData[CLCT.SERIAL_NUMBER] = ...

// register id

gd.registerDevice(hardwareId: ..., metaData: metaData, deviceModels: ...,
    callback: { (endpointId, error) in
        // reponse handler; contains code how to proceed returned endpoint id
    })
  • Create a virtual device implementing the device model
var virtualDevice: VirtualDevice = 
    gd.createVirtualDevice(gd.getEndpointId(), deviceModel: deviceModel);
  • Listen for control operations from enterprise client using a closure

virtualDevice.setOnChange({ event in
    var device: VirtualDevice = event.getVirtualDevice()
    // update the device with the new value
    var namedValue: NamedValue = event.getNamedValue()
    var attribute: String = namedValue.getName()
    var value: AnyObject = namedValue.getValue()
    // check namedValue.next() to see if there are
    // more values in the chain
    // ...
})
virtualDevice.setOnError({ event in
    var device: VirtualDevice = event.getVirtualDevice()
    // log error here
})
  • Update the virtual device when the data on the physical device changes
// set a value for a particular attribute in the virtual device
virtualDevice.set(HUMIDITY_ATTRIBUTE, withId: newValue)
  • Dispose of the gateway device client
gwd.close()

Storage Cloud Quick Start

This shows how to use a virtual device attribute to upload content to, or download content from, the Oracle Storage Cloud Service.

To upload or download content from a virtual device, there must be an attribute, field, or action in the device model with type URI. For the Oracle Storage Cloud Service, the URI type corresponds to the class StorageObject. When the attribute, field, or action of type URI is set to a StorageObject instance, the content is automatically synchronized with the Storage Cloud Service.

  • Uploading content

An instance of StorageObject is first needed to upload a file from a device client or from an enterprise client. The StorageObject is created using the createStorageObject API in DeviceLib.Client, which is the base class for EnterpriseLib.EnterpriseClient, DeviceLib.DirectlyConnectedDevice, and DeviceLib.GatewayDevice. The StorageObject names the object in storage, and provides the mime-type of the content. To set the input file, StorageObject API setInputPath(String) is used.

This example shows the typical use case from a DirectlyConnectedDevice. But the code for a GatewayDevice or `EnterpriseClient. is the same.

    let storageObject:StorageObject =
        directlyConnectedDevice.createStorageObject(name:"mediaSnapshot.jpg",
                                                    contentType:"image/jpg")
    storageObject.setInputPath(inputPath:"../images/mediaSnapshot.jpg");
    virtualDevice.set(attributeName:"snapshot", attributeValue: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.

  • Downloading content

In the virtualization API, the client is notified through an onChange event, onAlert event, or a call callback for an action. The value in the event is a StorageObject. To download the content, the output path is set on the StorageObject, and the content is synchronized by calling the StorageObject.sync() API.

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(attributeName:"snapshot", 
                              callback: { (event) in
            let namedValue:NamedValue = event.getNamedValue()
            let storageObject:StorageObject = namedValue.getValue() as? StorageObject
            // only download if image is less than 4M
            if storageObject.getLength() < 4 * 1024L * 1024L {
                do {
                    storageObject.setOutputPath(outputPath: "../downloads/" + storageObject.getName())
                    storageObject.sync()
                } catch {
                    print("cannot create file for download")
                }
            }
        }
    })
  • Checking synchronization status

A StorageObject is a reference to some content in the Storage Cloud. The content can be in sync with the storage cloud, not in sync with the storage cloud, or in process of being sync’d with the storage cloud. The synchronization happens on a separate thread, but can be monitored by setting a SyncCallback with setOnSync.

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(callback: { (event) in
        let storageObject:StorageObject = event.getStorageObject()
        if storageObject.getSyncStatus() == SyncStatus.inSync {
             // image was uploaded and can be deleted
        } else if storageObject.getSyncStatus() == SyncStatus.syncFailed {
             // image was not uploaded, take action!
        }
     })