Tutorial: Migrating OH 1 addon to OH 2/3: preparing (1/x) to

This tutorial is part of a series of tutorials helping with migrating openHAB 1 bindings to openHAB 2. This first tutorial describes how to get started.

Step 1: Installing the IDE

To start it’s best to freshly set up your development environment. For development ONLY USE JAVA 811. (openHAB 2 was 8, 3 is 11) Either install Eclipse or if you prefer VisualCode or IntelliJ. See the documentation on how to install: https://www.openhab.org/docs/developer/#setup-the-development-environment 5.
This tutorial describes the steps using Eclipse.

When installing Eclipse ONLY select openHAB Development in the Eclipse installer.

Step 2: Getting the openHAB-addons code

Make a fork on GitHub if you haven’t done so and clone the openhab-addons repo to the newly installed git directory. (Let me know if this description should be expanded here). To get started a good practice is to start with a new git branch:

git checkout -b <my binding branch>

Step 3: Create the new basis of your binding

With the create_openhab_binding_skeleton script in the openHAB-addons bundles folder we’re going to create the basis for your migrated binding. Run the following command to create the basis for your binding. The skeleton script also updates all files outside your binding folder that are needed to be adapted for the binding.

On Linux:

create_openhab_binding_skeleton.sh <binding name> "<your full name>" <your github name>

On Windows:

create_openhab_binding_skeleton.cmd <binding name> "<your full name>" <your github name>

This will generate a new binding in the bundles/org.openhab.binding.<binding name> folder. The following steps are all relative to this folder. More on the skeleton script can be found here: https://www.openhab.org/docs/developer/#develop-a-new-binding

The skeleton script is specific for bindings. If you want to migrate an io addon you can still use the script as a starting point. But you need to manually change binding in io. Action addons mostly also have a binding implementation and are combined or created as a binding.

Step 4: Copy the old binding into the new binding

The skeleton script generates an example binding. You can leave these files for now as they can be adapted later on. To get started we simply copy the openHAB 1 binding code into the newly generated code.

  • Copy openHAB 1 java files from src/main/java to the same directory in the openHAB2 binding
  • The readme will need some rework. Either override the READM.md in the new binding directory or copy it to a new name next to the generated README.md. The new README.md can be helpful because it’s structure. So you might want to keep it for now.
  • If you have any libraries you dependent on also copy them to a lib folder in your binding (for now)

Note: In the openHAB2 binding all java files should be in the package structure starting with: org.openhab.binding.<your binding>.internal. So any new file you add should be there.

Step 5: Importing the binding in Eclipse

In Eclipse Import the binding via File import. Select as an existing project.

If you have a dependency on guava you need to replace those method calls, because we don’t support guava anymore in bindings. In most cases only a single class was used from this library. You will have compile errors in this case.

Step 6: Add your binding to the debug/demo app

With openHAB2 Development and demo app is available. To debug your binding, add the dependency of your binding to the pom.xml of the demo app. (The one next to app.bndrun ). See also the Eclipse documentation for up-to-date details: Eclipse IDE | openHAB

Step 7: Hacking openHAB 1 dependencies out-of-it

Edit: With openHAB 3 this hack is not needed anymore, as the compatibility layer has been removed.

THIS IS TEMPORAY HACK TO HELP IDENTIFYING DEPENDENCIES
If you have copied the openHAB 1 code into the openHAB 2 binding all code will just look fine because the project has a dependency on the compatibility layer. To guide with the migration you can add the following dependency temporarily to your binding pom.xml. It will exclude the compatibility layer and give errors on all openHAB 1 classes. This directly gives you feedback on what classes you can use and what not.

    <dependencies>
        <dependency>
            <groupId>org.openhab.core.bom</groupId>
            <artifactId>org.openhab.core.bom.openhab-core</artifactId>
            <type>pom</type>
            <scope>compile</scope>
         <exclusions>
                <exclusion>
                    <groupId>org.openhab.core.bundles</groupId>
                    <artifactId>org.openhab.core.compat1x</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

Note: It might give an error on your pom, and when you’ve removed all the openHAB 1 references and want to test your code, you need to remove this dependency.

Next:

Now your ready starting migrating the binding. Specific steps will be in a follow up tutorial. I’ll update it here once available. You can start reading about openHAB 2 binding concepts here:

Tips

Here are some general tips when working with the code:

  • Remove @Since annotation from the java doc it’s not used anymore in openHAB addons
  • The @author tag should be @author <full name> - <Note>. The first entry is always: @author <full name> - Initial contribution
  • You can generate the license header in all source files with maven: mvn license:format -pl :org.openhab.binding.<your binding>
  • Compile your code with mvn clean install -pl :org.openhab.binding.<your binding>. This will also generate a report for you with valuable hints to improve your code. Or possible give errors for code convention violations.
  • Don’t catch the generic Exception, but catch the checked exception and/or RuntimeException. Only if a method would throw Exception you should catch it.
  • In Eclipse you can use Ctrl-1 to get a suggestion on how to do. For example with the exception if will give you the suggestion to wrap it in for you. Also you can use Ctrl-Shift-f to format a source file.
  • Don’t log to error. In general this is general used for system instability errors. Prefer use warn for bugs.
  • Channel naming. The most common usage (and preferred) is to use camel case for channels (thisIsAChannel) and for channel types hyphen syntax with small caps (this-is-a-channel-type).
  • Labels of channels in XML should have upper case for each first character of all words and be short.
  • Don’t put everything in big classes. Separate openHAB logic as much as possible from device specific code into several smaller classes and methods. This not only makes reviewing easier (and faster) but also makes migration easier as you can better see what to integrate. And makes it much more maintainable.

If you have any feedback or addendum please post in the comments. Or if you want to contribute to these tutorials pm me.

6 Likes

Sorry to bother you: exactly with those mentioned commands (and 2.5.0 version) I do not get any report other than the output being printed during the mvn command execution. Any hint?

You should something like this near the end of the compile log:

[INFO] Detailed report can be found at: file://<...>/git/openhab2-addons/bundles/org.openhab.binding.<binding>/target/code-analysis/report.html

Or if there is nothing to report it will print:

[INFO] Empty report will not be appended to the summary report.

Sorry, but none of it is visible after running this command…mvn-output-20190913.txt (15.9 KB)

It looks you have an older version on which your code is based on. The message has changed I see. It reports:

[INFO] No reports found !

The check in your branch is based on version 0.6.1 Current version is 0.7.0. You could do a pull --rebase followed by a push --force-with-lease to push the changes back.

2 Likes

This was the solution. Thanks!