A guide on creating a custom protocol adapter for the Home Device Manager system.
Overview
Adding device management support for your protocol allows you to manage all devices in your network in the same way via the HDM API regardless of the protocol they are using.
To accomplish this you need to implement a protocol adapter according to the device management abstraction introduced by the Home Device Manager.
Protocol Adapter SPI
The main components of an adapter are in an SPI represented by the com.prosyst.mbs.services.hdm.spi package. By introducing a separate SPI for adapter providers, the Home Device Manager isolates the low-level device representation from the top-level management application. The manager also performs additional processing on the data from adapters so as to save adapter developers efforts in notification, caching, etc., and to provide a home system with performance optimized in a best way.
Basically, you have to execute the following steps:
For further details refer to the SPI documentation as well.
Operations according to Protocol Features
The Home Device Manager abstraction introduces three types of adapter operations - add, search and remove, to cover the specifics of the conventional home protocols.
If the adapter, based on the underlying protocol, is capable of detecting newly-joined devices automatically, you do not need to implement the add operation but notify HDM when a new device is discovered. If a new device must be explicitly registered, then the adapter has to support "add". Refer to the "Describing Adapter Operations Support" section bellow for details on the "add" support.
The search operation stands for issuing requests to the network for newly-added or removed devices. If the protocol includes such a capability, then the adapter can support "search" to allow management application to launch such requests. Refer to the following "Describing Adapter Operations Support" section for details on the "search" support.
There is no rule that an adapter which supports add should not support search and vice versa. The range of accessible operations depends entirely on the features of the protocol.
Implementing Device Class Objects of Specific Classes
You have to provide skeletons for the separate classes of device class objects that you expect to appear in the connected home network. Each device class object has to implement at least two interfaces: the DeviceClassObjectSpi interface and a device class interface defining its capabilities. For example, a wind sensor has to implement a DeviceClassObjectSpi and com.prosyst.mbs.services.hdm.deviceclasses.WindSensor.
Optionally a Device Class Object may implement several other interfaces in order to support additional HDM features.
Implement DeviceClassObjectSpi
The DeviceClassObjectSpi interface describes each device class object to the Home Device Manager in a universal way.
Indicate the Implemented Device Class Interface
To indicate the functionality of the device class object, represented by the device class interface it implements, return the device class name in the getDeviceClass method of the DeviceClassObjectSpi.
Indicate the Device Class Type
In the getType method, return additional information about the function of the Device Class that is not covered in the Interface metadata. For example, the Meter Device Class Object interface can have types energy, gas, water, heat etc.
Provide Information about Supported Properties and Operations
In the getPropertyNames method of the DeviceClassObjectSpi, list the properties that the device class object has depending on the device's physical capabilities.
You can return property-specific metadata, such as access, description, unit, etc. for each property through the getPropertyMetadata and getOperationsMetadata methods. You can retrieve the default metadata of the Device Class interface with the getDefaultPropertyMetaData and getDefaultOperationMetaData methods of the HomeDeviceAdminSpi class.
The following Java code examples demonstrate how to implement these methods to retrieve the default property and operations metadata:
public Map getPropertyMetaData(String dc, String dcType, String property) {
HomeDeviceAdminSpi hdaSpi = this.hdaSpi;
return (hdaSpi == null) ? null : hdaSpi.getDefaultPropertyMetaData(dc, dcType, property);
}
public Map getOperationMetaData(String dc, String dcType, String operation) {
HomeDeviceAdminSpi hdaSpi = this.hdaSpi;
return (hdaSpi == null) ? null : hdaSpi.getDefaultOperationMetaData(dc, dcType, operation);
}
Provide Polling Information
The protocol adapter provides a polling interval for every Device Class Object property:
You can also support a default polling interval specific to each property of the device class object by providing an implementation of the getDefaultPollingInterval method. The Home Device Manager uses the default interval to initialize the polling mechanism for this device class object property. To indicate that the polling mechanism should not be running for a property, your adapter should return a default interval of 0. For example, you can specify a minimal polling interval of 5 seconds and 0 as the default polling interval for a specific device class object property. This is useful if the property has access "R" and not "RE", i.e. the property is only readable and no events are sent upon its change and it has one and the same unchangeable value.
Implement a Device Class Interface
Implement one Device Class Interface, either one of the interfaces that are available in HDM or one designed by you. The methods from the Device Class Interface have to be implemented synchronously (you can introduce a timeout for receiving acknowledgment to avoid blocking in cases of connection failure).
When a Device Class property is changed or a Device Class operation is executed, notify the HDM via the HomeDeviceAdminSpi callback (explained below).
Additional Interfaces
Optionally a Device Class Object can implement several other interfaces in order to support additional HDM features:
Persistent Device Class Object Properties
Optionally, the Home Device Manager can store the values of certain Device Class Object properties in its database so that the values are available even when the device is offline.
To enable this feature, implement the PersistableDeviceClassObject interface in your Device Class and in the getType method, return the properties which you want to store.
HDM users will be able to retrieve the last captured values of these properties at any time.
Default Device Class Object Properties Values
There are home protocols which set default values to their Device Class Object properties, as an indication that the actual values have not been yet retrieved from the device. Different protocols use different values as "default". The DefaultDeviceClassObject interface abstracts away that difference by providing a unified mechanism for the Home Device Manager to check if a given property has or has not been set.
To enable this feature, implement the DefaultDeviceClassObject and in the isDefault method return true if the current value of the property which is passed as argument to the method is the default one.
HDM users will be able to check if the value of a given property is real device data (as opposed to a default value) with the is.default metadata property.
Implementing the HomeDeviceSpi Interface
Each home device that your adapter will handle implements the HomeDeviceSpi interface. The Home Device Manager will use the HomeDeviceSpi instances to retrieve basic details identifying the device and to access the device class objects representing its capabilities.
Return Contained Device Class Objects
The device's DeviceClassObjectSpi objects must be associated with a container HomeDeviceSpi object and must be delivered when the getDeviceClassObjects method is executed.
Provide Device Properties
Provide to the Home Device Manager a device UID, type, friendly name, vendor and version, by implementing the relevant method from the interface.
If the device has other properties specific to the used protocol, you can return them in the getProperties method.
There are two special additional properties - CONTROLLER_ID which shows the ID of the controller handling a device and SECURE indicating if the connection to the device is secure.
Add Support for Property Updates
If the protocol allows it you can add support for changing certain device properties by implementing the updateProperties method of the HomeDeviceSpi.
Indicate Device Status
Implement the getStatus method to return the status one of the HDM status constants.
In case of connection failure you can additionally provide the error that has caused the failure by implementing the getError method.
Add Support for Property Updates
If the protocol allows it, you can add support for support for arranging devices in hierarchies thus enabling the Home Device Manager to represent the nature of complex physical devices in a best way. Indicate the children of a device as result from the getChildUIDs method execution. Similarly, through the getParentUID method indicate a parent device.
Provide Information for a Controller Device
If the device will represent a network controller, return as device type HomeDevice.TYPE_CONTROLLER, and assign it a unique ID within the scope of the protocol as value of the HomeDevice.CONTROLLER_ID.
Implementing the HomeProtocolAdapter Interface
The Home Device Manager interacts with a protocol adapter using the protocol's com.prosyst.mbs.services.hdm.spi.HomeProtocolAdapter implementation. Through it, the Home Device Manager requests the adapter to search the network for devices, contacts new devices, etc., as well as passes a callback object so that the HDM can be notified of changes in the devices.
Notifying the Home Device Manager about Devices
When the Home Device Manager detects your HomeProtocolAdapter it will call the setHomeDeviceAdminSpi method. Save the HomeDeviceAdminSpi callback passed as the method's argument and use it to transmit information to the Home Device Manager about newly-created home devices and device class objects:
After each method call, the Home Device Manager will save the state of your network in the framework's storage.
Describing Adapter Operations Support
The Home Device Manager abstraction introduces three types of operations - add, search and remove, to cover the specifics of the conventional home protocols. If your protocol supports some of them implement their execution:
Add
If allowed by the underlying protocol driver, an adapter might be implemented to support add requests from the Home Device Manager. For example, if the protocol does not define automatic discovery of newly-joined devices. In such a case, the adapter is expected to contact the addressed device through the network, retrieve required data from the device and transform the data in a HomeDeviceSpi object.
Indicate that your adapter supports device "add" by including the flag ProtocolAdapterInfo.OPERATION_ADD in the bitwise OR bitmask returned in the getOperations of the ProtocolAdapterInfo.
Implement the addHomeDevice method of the HomeProtocolAdapter interface for manual device registration. Use the properties within the passed input Map argument, such as the UID, to identify the device in the network.
Search
In certain cases, a protocol adapter can be capable of searching the associated network for devices with specific features. The search might result in refreshing the configuration of devices the adapter is responsible for, that is, new devices might have joined the network, others might be removed, etc.
Indicate that your adapter supports device "search" by including the flag ProtocolAdapterInfo.OPERATION_SEARCH in the bitwise OR bitmask returned in the getOperations of the ProtocolAdapterInfo.
If the protocol supports doing a manual refresh of the list of connected devices implement the searchHomeDevices method.
Remove
If the protocol supports the explicit removal of devices from the network implement the removeHomeDevices method.
Implement the ProtocolAdapterInfo Interface
Implement the ProtocolAdapterInfo interface by adding information about your protocol adapter that is accessible to its users:
Return your ProtocolAdapterInfo implementation in the getInfo method of the HomeProtocolAdapter.
The metadata that you have to provide in the ProtocolAdapterInfo must cover the properties defined in all supported device classes.
Registering the HomeProtocolAdapter Implementation as an OSGi Service
Register the HomeProtocolAdapter instance as a service in the OSGi framework. The Home Device Manager will automatically discover the presence of the adapter and will attach it to its system.