Extending the Remote Configuration of Your Device (RCI)

The RCI service is an optional feature for Cloud Connector applications that allows for remote configuration, control and information exchange between a device and Device Cloud.

Your device's information is easily accessible and graphically represented within Device Management in order to facilitate remote inspection and modification. To view your device's configuration settings simply open the device's Properties page by double-clicking on your device within the Device list. From the device's Properties page you can review or change your device's configuration settings remotely.

To enable and extend the RCI service you must:

  1. Configure Cloud Connector.
  2. Create your descriptor file.
  3. Implement the RCI code extensions.

Configuring Cloud Connector

RCI service enablement is defined by the enable_rci property. It is located in the Services Settings section within the connector_config.txt file of your project. It must be set to True in order for you to be able to remotely configure your device.

enable_rci=True

When the RCI service is enabled, you will be able to remotely configure and review some basic data from Device Management:

The examples of the Cloud Connector platform implementation given in this SDK, Java SE PC, allow the applications to extend the remote configuration. This way, it is possible to add additional device settings and information, that can be remotely accessed and configured, to the basic configuration offered by the provided Cloud Connector platform customization for the PC.

To create a custom extension of the remote configuration, the RCI service must be enabled (enable_rci=True) and other parameters of the connector_config.txt file need to be defined:

You also need to configure all the settings described in the Connecting to Device Cloud topic to establish a proper connection with Device Cloud.

Tip The configuration of Cloud Connector comprehends more settings that are not going to be covered in this section. Previous and next topics also cover some of the configuration that might be needed. For more information about all the settings, read the Cloud Connector Configuration section.

Creating Your RCI Descriptor File

RCI descriptors are XML files that describe the configurable settings and state information that will be remotely available. The contents of the file will be graphically represented in Device Cloud, allowing you to easily review and change your device configuration.

Your descriptor file should be located in the path configured in descriptor_loc, and its definition has to be provided using a specific syntax to define a group of settings, state information, errors, setting types, etc.

For more information on how to define your descriptor file go to:

http://ftp1.digi.com/support/documentation/90000569_G.pdf

You can find a sample descriptor file in the RCI Sample within the root folder of the project:

Example of RCI descriptor file
<?xml version="1.0" encoding="utf-8"?>
<query_descriptor>
	<!-- Descriptor for <query_setting/> -->
	<descriptor element="query_setting" desc="Retrieve device configuration" >
		<!-- 'Custom' group to manage some custom settings from Device Cloud -->
		<!-- This group will appear under the section called 'Configuration' -->
		<!-- Defined 'read_write' access for all the settings in the group -->
		<!-- The settings of this group are defined by 'custom_format' -->
		<descriptor element="custom" desc="Custom settings" access="read_write" format="custom_format"/>
  
		<!-- Definition of the format to be used in the 'query_setting' and 'set_setting' descriptors -->
		<format_define name="custom_format">
			<!-- String setting with a maximum length of 20 chars -->
			<element name="stringSetting" desc="String setting" type="string" max="20" default=""/>
			<!-- Integer setting between -10 and 10 -->
			<element name="intSetting" desc="Integer setting" type="int32" min="-10" max="10" default="0"/>
			<!-- Enumeration setting -->
			<element name="enumSetting" desc="Enumeration setting" type="enum" default="value 2">
				<value value="value 1"/>
				<value value="value 2"/>
				<value value="value 3"/>
			</element>
			<!-- Errors -->
			<error_descriptor id="1" desc="Internal error (save failed)"/>
			<error_descriptor id="2" desc="Not enough permission for specified field"/>
			<error_descriptor id="3" desc="Field specified does not exist"/>
			<error_descriptor id="4" desc="Field specified is read only"/>
			<error_descriptor id="5" desc="Invalid String setting value"/>
			<error_descriptor id="6" desc="Invalid Integer setting value"/>
			<error_descriptor id="7" desc="Invalid Enumeration setting value"/>
		</format_define>
	</descriptor>

	<!-- Descriptor for <set_setting/> -->
	<descriptor element="set_setting" desc="Set device configuration" >
		<!-- 'Custom' group to manage some custom settings from Device Cloud -->
		<!-- This group will appear under the section called 'Configuration' -->
		<!-- Defined 'read_write' access for all the settings in the group -->
		<!-- The settings of this group are defined by 'custom_format' -->
		<descriptor element="custom" desc="Custom settings" access="read_write" format="custom_format"/>
	</descriptor>

	<!-- Descriptor for <query_state/> -->        
	<descriptor element="query_state" desc="Request device current state" >
		<!-- 'Memory' group to show some memory information -->
		<!-- This group will appear under the section called 'System Information' -->
		<!-- Defined 'read_only' access for all the settings in the group -->
		<descriptor element="memInfo" desc="Memory" access="read_only" >
			<!-- Total amount of free memory available to the JVM -->
			<element name="freeMemory" desc="Free Memory" type="uint32" units="bytes"/>
			<!-- Maximum amount of memory the JVM will attempt to use  -->
			<element name="maxMemory" desc="Maximum Memory" type="uint32" units="bytes"/>
			<!-- Total memory currently available to the JVM -->
			<element name="totalMemory" desc="Total Memory" type="uint32" units="bytes"/>
		</descriptor>
	</descriptor>
</query_descriptor>

Implementing the RCI Extension

Once the descriptor file is created, you need to define the class used to obtain and set the values of the elements within the descriptor. An instance of this class must be passed to the CloudConnector constructor.

RCI extension registration
[...]
// New Cloud Connector object
CloudConnector connector = new CloudConnector(new MyRCIExtension());
[...]

This extension class, MyRCIExtension, should implement the IGeneralRCIExtension interface, which includes three methods to manage the settings in the RCI extension:

IGeneralRCIExtension implementation example, MyRCIExtension
[...]

public class MyRCIExtension implements IGeneralRCIExtension { 
	// Group names
	private static final String MEM_INFO_GROUP = "memInfo";
	private static final String CUSTOM_GROUP = "custom";

	// Memory state group elements names
	private static final String FREE_MEM_STATE = "freeMemory";
	private static final String MAX_MEM_STATE = "maxMemory";
	private static final String TOTAL_MEM_STATE = "totalMemory";

	// Custom settings group elements names
	private static final String STRING_SETTING = "stringSetting";
	private static final String INT_SETTING = "intSetting";
	private static final String ENUM_SETTING = "enumSetting";

	@Override
	public String getSettingValue(String group, String setting, int index, String name) {
		switch (group) {
			case MEM_INFO_GROUP:
				return getMemInfoStateValue(setting);
			case CUSTOM_GROUP:
				return getCustomSettingValue(setting);
			default:
				// Error: Group does not exist.
				System.out.println("Group '" + group + "' does not exist");
				return null;
		}
	}

	@Override
	public String setSettingValue(String group, String setting, String value, int index, String name) {
		switch (group) {
			case CUSTOM_GROUP:
				return setCustomSettingValue(setting, value);
			default:
				// Error: Group does not exist.
				System.out.println("Group '" + group + "' does not exist");
				return null;
		}
	}
  
	@Override
	public String handleZigbeeRequest(String data) {
		// Not handled
		return null;
	}

	/**
	 * Retrieves the value of the given {@value #MEM_INFO_GROUP} state.
	 * 
	 * @param state the state to get the value.
	 * @return the value, {@code null} if error.
	 */
	private String getMemInfoStateValue(String state) {
		switch (state) {
			case FREE_MEM_STATE:
				return ""+Runtime.getRuntime().freeMemory();
			case MAX_MEM_STATE:
				return ""+Runtime.getRuntime().maxMemory();
			case TOTAL_MEM_STATE:
				return ""+Runtime.getRuntime().totalMemory();
			default:
				// Error: State field does not exist.
				System.out.println("State field '" + state + "' does not exist");
				return null;
		}
	}

	/**
	 * Retrieves the value of the given {@value #CUSTOM_GROUP} setting.
	 * 
	 * @param setting the setting to get the value.
	 * @return the value, {@code null} if error.
	 */
	private String getCustomSettingValue(String setting) {
		switch (setting) {
			case STRING_SETTING:
				[...]
				return [...];
			case INT_SETTING:
				[...]
				return [...];
			case ENUM_SETTING:
				[...]
				return [...];
			default:
				// Error: Setting field does not exist.
				System.out.println("Setting field '" + setting + "' does not exist");
				return null;
		}
	}

	/**
	 * Sets the value of the given {@value #CUSTOM_GROUP} setting.
	 * 
	 * @param setting the setting to set the value.
	 * @param value the new value.
	 * @return Error string. Empty string means no error.
	 */
	private String setCustomSettingValue(String setting, String value) {
		String error = "";
		switch (setting) {
			case STRING_SETTING:
				[...]
				break;
			case INT_SETTING:
				[...]
				break;
			case ENUM_SETTING:
				[...]
				break;
			default:
				// Error: Setting field does not exist.
				error = "Setting field '" + setting + "' does not exist";
				System.out.println(error);
		}
		return error;
	}
}

Reviewing Your Device’s Remote Configuration

The configuration information for a device is displayed by opening its Properties page. You can open a device’s Properties page by double-clicking on the device in the Device list, a new tab will be added with a menu-tree on the left and the corresponding properties information on the right.

The properties added in our custom XML above generates two different groups:

  1. Memory inside System Information, with 3 state elements: Free Memory, Maximum Memory and Total Memory.

  2. Custom settings inside Configuration, with 3 setting elements: String setting, Integer setting and Enumeration setting.

Use the Refresh button to get the information directly from the device, and Save to change its configuration values.

You can also review and modify your device’s configuration via Web Services. Try it by using the included API Explorer; navigate to Documentation > API Explorer and select Examples > SCI > RCI. From this category you can:

For example, to get the device state values of the Memory group, the command looks like the following:

<sci_request version="1.0"> 
	<send_message cache="false"> 
		<targets>
			<device id="00000000-00000000-00000000-00000000"/>
		</targets> 
		<rci_request version="1.1">
			<query_state>
				<memInfo/>
			</query_state>
		</rci_request>
	</send_message>
</sci_request>

And the answer would be similar to:

<sci_reply version="1.0">
	<send_message>
		<device id="00000000-00000000-00000000-00000000">
			<rci_reply version="1.1">
				<query_state>
					<memInfo>
						<freeMemory>10808688</freeMemory> 
						<maxMemory>259522560</maxMemory> 
						<totalMemory>16252928</totalMemory>
					</memInfo>
				</query_state>
			</rci_reply>
		</device>
	</send_message>
</sci_reply>

Sample Application Code

The RCI Sample demonstrates the RCI service of Device Cloud. This sample will teach you how to enable the service and extend the remote configuration to be able to remotely manage your device.

The sample includes its own connector_config.txt file to properly configure Cloud Connector to establish a connection and extend the basic configuration.

The sample code extends the RCI descriptor by:

Caching of Descriptors from Device Cloud

Since Device Cloud supports a wide variety of devices, it relies on the device to provide device descriptors as well as state and configuration settings to Device Cloud when the device first connects to Device Cloud.

When Device Cloud displays Properties page information, the information displayed is pulled from Device Cloud’s database (if it exists); otherwise the information is pulled directly from the device. There are 2 different types of data cached:

The descriptor information is cached for the trio Vendor ID (vendor_id in the connector_config.txt), Device Type (device_type in the connector_config.txt) and Firmware Level (target 0 version or, if not defined, firmware_version in the connector_config.txt). Once Device Cloud has a descriptor for this 3 values it will not ask for it again unless the cache is cleaned or any of the values change. To display the RCI descriptor changes in Device Cloud you can:

Regarding the values of the settings in the descriptor, in order to force Device Cloud to update its database with a current copy of the device’s configuration and state information, click the Refresh button within the Properties page.

Tip

It is recommended that you click the Refresh button within a device’s Properties page each time you access the page in order to ensure that the most up to date information is displayed.