This post probably starts the most interesting part of the project: interfacing the sensor with
OpenHAB through enOcean radio protocol
Hardware setup
The hardware setup is shown in picture below
The PC runs OpenHAB and sends command to the enOcean transceiver to the Raspberry Pi board using the USB300 USB dongle. The Raspberry Pi board, in turn, sends notifications to the OpenHAB.
Software setup
Software setup is not so easy. Our sensor requires the use of an enOcean profile that is currently not supported neither by OpenHAB not by EOLink library. The purpose of a profile in the enOcean communication standard is easily said. The profile makes the receiver able to understand the content of the telegrams sent out by a field device. As a matter of fact, enOcean is a protocol targeted to ultra-low-power devices. For this reason, the protocol has been designed to minimize the frame length sent out by the field devices. During the installation of the field device, a "teach" telegram is sent out by the device (typically this telegram is sent out on user request, for example by pressing a push button). The "teach" telegram contains information about the profile the field device adheres to. The receiver stores the device ID and the profile. In this way, no extra data is required in the normal telegrams, because the receiver already knows (thanks to the profile it stored during the learning process) how to interpret data in the telegrams.
So, we are facing a complex problem because we need to
- 1. setup a development environment to build and debug OpenHAB from source code
- 2. Extend the current OpenHAB enOcean binding to implement a new custom enOcean profile
- 3. modify the EOLink library to support a new custom profile (I talked about building the EOLink library from source code in round 1)
- 4. configure OpenHAB to use the new profile
- 5. handle commands and notifications in the sensor application running on the Raspberry Pi board
Let's start with step 1...
Build OpenHAB from source code
Here are step-by-step instructions (I installed all this stuff on a virtual machine running Windows XP)
- 1. Create a local clone of the openHAB repository by running
git clonehttps://github.com/openhab/openhab
in a suitable folder (C:\Documents and Settings\Administrator\OpenHAB)
- 2. Download and install oracle jdk 1.7
- 3. Download and install the Yoxos Installer from https://yoxos.eclipsesource.com/downloadlauncher.html
- 4. Download and execute the file openHAB.yoxos from http://dl.dropbox.com/u/15535378/openHAB.yoxos
(in Linux that can be done via command line ./yoxos openHAB.yoxos ). This will install you an Eclipse IDE with all required features to develop for openHAB. Alternatively, you can install all required plugins on top of an existing Eclipse 4.2.2 installation using this update site or download a full distribution from Yoxos if you register an account there.
- 5. Create a new workspace.
- 6. Choose "File" -> "Import" -> "General" -> "Existing Projects into Workspace", enter your clone repository directory as the root directory and press "Finish".
- 7. After the import is done, you have to select the target platform by selecting "Window" -> "Preferences" -> "Plug-in Development" -> "Target Platform" -> "OpenHAB" from the main menu. Ignore compilation problems at this step.
- 8. Now you need to run code generation for a few parts of OpenHAB. To do so, go to the project org.openhab.model.codegen and run the prepared launch files. For each .launch file, select "Run As->x Generate abc Model" from the context menu. Please follow the order given by the numbers. On the very first code generation, you are asked in the console to download an ANTLR file, answer with "y" and press enter on the console. (See https://groups.google.com/forum/#!topic/openhab/QgABTJAkHOg if you're getting "Could not find or load main class org.eclipse.emf.mwe2.launch.runtime.Mwe2Launcher")
- 9. All your project in the workspace should now correctly compile without errors. If you still see error markers, try a "clean" on the concerned projects. If there are still errors, it could be that you use JDK 1.6 instead of JDK 1.7. If you still have problems try (as I did) to delete the .project from org.openhab.archetype.action and org.openhab.archetype.binding
- 10. To launch openHAB from within your IDE, go to "Run" -> "Run Configurations" -> "Eclipse Application" -> "OpenHAB Runtime"
Unfortunately I realized that the support for sending commands to enOcean actuators provided by the enOcean binding is very poor. But, thanks to the open source community, I found another implementation of the enOcean binding here
To install this new binding in the OpenHAB development environment, just "File" -> "Import" -> "Existing project into workspace". A project named org.openhab.binding.aleoncean will be created.
In the Ecplise IDE, right-click in the "Project explorer" window and click "Refresh". The new Aleoncean binding will be visible in the "Project explorer" and you should be able to build and run the OpenHAB runtime.
Making changes to OpenHAB
During the preliminary tests I found an issue in the current implementation of OpenHAB of the Contact item.
The "Contact" item does not support the On/Off values (just Open/Closed). Because I'd like to set contact status using On/Off values, I made the following change to the ContactItem.java file (in org.openhab.core.library project)
private static List<Class<? extends State>> acceptedDataTypes = new ArrayList<Class<? extends State>>();
private static List<Class<? extends Command>> acceptedCommandTypes = new ArrayList<Class<? extends Command>>();
static {
//New code begins here
acceptedDataTypes.add(OnOffType.class);
//New code ends here
acceptedDataTypes.add(OpenClosedType.class);
acceptedDataTypes.add(UnDefType.class);
}
public ContactItem(String name) {
Making changes to Aleoncean binding
In the Aleoncean binding, I found an issue related to the ConverterFactory class. The getConverterFactory method of the ConverterFactory class always returns null because the checkTypeClass method looks for accepted commands, but a Contact item does not support any command. So I changed the checkTypeClass method as shown below
private static boolean checkTypeClass(final Class<? extends StandardConverter> converterClass,
final List<Class<? extends State>> acceptedDataTypes,
final List<Class<? extends Command>> acceptedCommandTypes) {
try {
final Field fieldStateType = converterClass.getField(FIELD_STATE_TYPE_CLASS);
final Field fieldCommandType = converterClass.getField(FIELD_COMMAND_TYPE_CLASS);
final Class<? extends State> converterStateTypeClass = (Class<? extends State>) fieldStateType.get(null);
final Class<? extends Command> converterCommandTypeClass = (Class<? extends Command>) fieldCommandType.get(null);
//Old code
//return acceptedDataTypes.contains(converterStateTypeClass) &&
// acceptedCommandTypes.contains(converterCommandTypeClass));
//New begins code
return acceptedDataTypes.contains(converterStateTypeClass) &&
((acceptedCommandTypes.size() == 0) ||
acceptedCommandTypes.contains(converterCommandTypeClass));
//New code ends here
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException ex) {
return false;
}
}
This is just the start... the Aleoncean binding uses an external project to implement profiles and the actual communication with the USB300 dongle.
Next step will be to modify such external project to implement the enOcean profile we need...