Modify a zwave binding jar to add/change a zwave device while waiting for a build

Tags: #<Tag:0x00007f2fb0c5d118> #<Tag:0x00007f2fb0c5cfd8> #<Tag:0x00007f2fb0c5ce70>

**PLEASE don’t use this without also updating the device database! As a community, we make the most progress when everyone contributes!**

I’ve seen several posts where people have made changes to the device database and they were eager to try out their new shiny gizmo, or wanted to test a change/fix an issue, before it was included in a build. Here is a method to update the zwave jar with a modified device Thing definition, without having to use an IDE to modify and compile the jar. This method could also be used to modify other bindings. The tutorial is written for OH systems running on Linux, but most/all may be applicable for Windows. Please use at your own risk!

  1. If you installed the zwave binding through PaperUI or Karaf, then uninstall it and restart OH.

  2. Download the jar that you want to modify, and save into a working directory outside of any OH directory. Typically, you will download a snapshot version of the jar from

  3. In the same directory where you have the jar, create the following directory structure (case sensitive). You’re basically recreating the directory structure inside the jar. Jar files are archives, which can be extracted and viewed, just like a zip file. You can browse into the jar to compare it to the directory structure you’ve made. Step 5 will show you how to find the [vendor].

     |_ [working directory where jar was downloaded to]
         |_ ESH-INF
             |_ thing
                 |_ [vendor]
  4. Go to the device database, follow the instructions for requesting an account (if you haven’t already), login, and create or modify the device.

  5. Export the XML from the database (from the top of the device’s page, Export> OpenHAB 2). Copy the contents of the XML and paste it into a new text file. In the XML, you will find a thing-type id, which is in the format of [vendor]_[XML file name with some extra zeros]. Don’t worry about the extra zeros… they won’t be an issue. Save the XML file into the [vendor] directory that you created, using the file name from the XML file with an xml file extension.

  6. If you currenty have the zwave binding manually installed (copied a jar into /addons), it is easiest to name this new jar the same as the current jar that you are using so that the older one is overwritten by the new one. Otherwise, OH will cache the older file after it has been deleted, and you will need to restart OH to get rid of it.In a terminal, go to the parent working directory and execute…

jar -uf org.openhab.binding.zwave-2.4.0-SNAPSHOT.jar ./ESH-INF/thing/[vendor]/[XML file name].xml
  1. Copy the jar from your working directory into the /addons folder.
  2. The binding will now start. If you were modifying the XML for a device that you have already included, then delete the Thing (Configuration> Things> Delete in Habmin or PaperUI), and then run discovery for the binding. This is needed to pickup the new Thing definition in the XML. If you have a static Thing file for a device that you have already included, then move the file out of OH and then move it back to delete the Thing.
  3. When a new build is available with the changes that you made to the device database, delete the jar, restart OH, install the updated binding, and delete/rediscover the Thing like in step 8.

Playing the role of the noob here.

  1. How do I browse into it?

Answer: The jar file is just a zip file so you can use any program that can open a zip file to open the jar file. You can also get a listing of the contents using jar -tf org.openhab.binding.zeave-2.4.0-SNAPSHOT.jar.

  1. How do I know what the correct manufacturer name is?

Answer: Check the box or the manual.

  1. How do I choose what device I need to extract the XML from? Do I choose an arbitrary XML file, does it have to be from the same manufacturer? Does it have to be the same type of device?

Answer: ???

  1. What do I change?

Answer: Copy the values from the xml file in the userdata/zwave folder that corresponds with the node of the device?

1 Like

Since the device should always exist in the database, just export the XML. You will find the name inside. I will modify the instructions in the first post to make this clearer.

See above

The XML file in /userdata/zwave is a completely different file.

1 Like

So really step zero is adding the device to the zwave database and exporting the XML from there? And it’s this XML that we are adding to the jar file so that we can use the device until that new entry makes it to the nightly builds?

I think that was the part I was missing. Because if the XML file for my device is already in the jar file I shouldn’t have to do anything and it is there and works, right?

Yes, this is best. I just rewrote the whole thing around this first step.

This would only be needed if you were updating the device database and wanted to use those changes before the build came out. Or if you were testing a change, fixing an issue, etc. before the change was included in a build.

1 Like

The Cloudbees link no longer works.

I can find info on recent pull requests for the Z-Wave binding on

Where can a recently built Z-Wave binding be found?

Cloudbees kicked us off their service awhile back so we set up our own build server. The site would be the place you would look normally. However, the builds are currently broken so it seems possible that the OH2 addons are not being successfully built right now.

I’ll update the OP. You can always go to bintray for jars too. Here’s zwave…

Would this then be the correct link?

Looks like it.

I uninstalled the Z-Wave binding (from the 2.5.0 snapshot), then downloaded the latest successfully built Z-Wave binding JAR file to /usr/share/openhab2/addons.

Upon restarting OpenHAB2 I saw the following error message:

org.osgi.framework.BundleException: Could not resolve module: org.openhab.binding.zwave [201]
Unresolved requirement: Import-Package:

It’s apparently due to the absence of a now required feature: openhab-transport-serial.

openhab> bundle:list | grep -i zwave
250 │ Installed │  80 │     │ ZWave Binding
openhab> bundle:list | grep serial
openhab> feature:install openhab-transport-serial
openhab> bundle:list | grep serial                                                                                                                             
251 │ Active   │  80 │ 3.14.0                 │ nrjavaserial
252 │ Active   │  80 │ 3.15.0.OH2             │ nrjavaserial
openhab> logout

Works like a charm!

Nope, already since two years :rofl:

When using a manual binding installation, you need to manually install any dependencies too. And you will need to reinstall them after clearing the cache. This script may be helpful…


Hi @5iver ,
I tried this but got following questions/problems on running an OH 2.4 on a PI3:

  1. Where can I download a org.openhab.binding.zwave-2.4.0.jar (from stable release) ?
    I found one on my local disk and used this
  2. I deinstalled my zwave binding and restarted OH2. After copying the modified jar file to /usr/share/openhab2/addons nothing happened, no zwave binding started… what am I doing wrong?

Thanks for any support in advance.

sorry, point 2 is solved. I think it just took some time and maybe the restart did it, but the jar file is loaded.
is it ok to use this 2.4.0 jar file from my locla disk as mentioned above in point 1?

Yes… it is the same as what you would download.

I get an error in the OH log, saying it cannot parse my added xml file:
I downloaded this file from the zwave-binding github on a windows machine and copied it to my RI3 via WinSCP. Do you think this could cause the problem due to CR/LF differences?

(upload://wL5IjH79YPJB9OCzXBXtr51ADBo.xml) (202.0 KB)

2019-09-08 15:28:03.908 [WARN ] [ig.xml.osgi.XmlDocumentBundleTracker] - The XML document ‘/ESH-INF/thing/devolo/mt2759_0_0.xml’ in module ‘org.openhab.binding.zwave’ could not be parsed: html
com.thoughtworks.xstream.mapper.CannotResolveClassException: html
at com.thoughtworks.xstream.mapper.DefaultMapper.realClass( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.mapper.DynamicProxyMapper.realClass( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.mapper.PackageAliasingMapper.realClass( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.mapper.ClassAliasingMapper.realClass( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.mapper.ArrayMapper.realClass( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.mapper.SecurityMapper.realClass( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.mapper.MapperWrapper.realClass( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.mapper.CachingMapper.realClass( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.core.util.HierarchicalStreams.readClassType( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.core.TreeUnmarshaller.start( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.unmarshal( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.XStream.unmarshal( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.XStream.unmarshal( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.XStream.fromXML( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at com.thoughtworks.xstream.XStream.fromXML( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at org.eclipse.smarthome.config.xml.util.XmlDocumentReader.readFromXML( ~[101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at org.eclipse.smarthome.config.xml.osgi.XmlDocumentBundleTracker.parseDocuments( [101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at org.eclipse.smarthome.config.xml.osgi.XmlDocumentBundleTracker.processBundle( [101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at org.eclipse.smarthome.config.xml.osgi.XmlDocumentBundleTracker.access$6( [101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at org.eclipse.smarthome.config.xml.osgi.XmlDocumentBundleTracker$ [101:org.eclipse.smarthome.config.xml:0.10.0.oh240]
at java.util.concurrent.Executors$ [?:?]
at [?:?]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201( [?:?]
at java.util.concurrent.ScheduledThreadPoolExecutor$ [?:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker( [?:?]
at java.util.concurrent.ThreadPoolExecutor$ [?:?]
at [?:?][mt2759_0_0.xml|attachment]

mt2759_0_0.xml (202.0 KB)

Try downloading it from jfrog and put the jar file in your addons folder. Uninstall the 2.4 snapshot zwave binding first: