ZigBee binding discusion

Yeah, that is a way better idea, to do that I would have to use method:

updateProperties(Map<String, String> properties);

Am I correct?

In ZigBee API method AddSceneResponse addScene(AddScenePayload scenePayload) the variable scenePayload is very contrived in the end I just opted out of doing it and chose a simpler solution.

Strange, I couldn’t find these clusters in handler/clusters directory…

Yes - that’s correct.[quote=“Saukijanas, post:20, topic:12895”]
Strange, I couldn’t find these clusters in handler/clusters directory
[/quote]

No - I didn’t add them into the current implementation. They were implemented a long time ago in the first version of the binding (maybe 1 year ago) but when I refactored I didn’t put them back in again. I was hoping that it would be easier to review/merge with a smaller PR and we could get the binding included into the main repository and I could then add the enhancements… It hasn’t turned out that way so I will add these back shortly.

Okay, thanks. I am looking forward to comparing how you written those clusters with mine (shouldn’t be too different I hope).

Concerning properties: ZigBeeClusterHandler must inherit BaseThingHandler to allow the use of methods for property editing (if I understand everything correctly), but you haven’t used any inheritance on ZigBeeClusterHandler, also on line 88 you have an editied BaseThingHandler method:

public void handleCommand(Command command)

but in its documentation you state that this command has two parameters: ZigBeeThingChannel and Command (just like the original BaseThingHandler method). Is documentation just wrong or did you mean to inherit this method from BaseThingHandler?

The cluster handler shouldn’t inherit from the BaseThingHandler - this would not work as it is not a thing handler! If you want to set properties, then you will need to find another way to do it. The cluster handler could expose the properties, and these could then be updated in the thing handler for example.

It’s a cut and paste error I suspect. As above, the cluster handler is NOT a thing handler so it should not inherit from BaseThingHandler.

Thanks for the tip, Chris! I’ve added 2 new methods (getProperties() and renewProperties()) in ZigBeeThingHandler and in ZigBeeClusterHandler I’ve added an instance of ZigBeeThingHandler so I could access them in my clusters. Now I just call getProperties() and renewProperties() instead of editProperties() and updateProperties(). Not sure if it is the most efective way of doing things though…

Hey, @chris!

While going through Logs trying to determine why none of the channels except Switch channel show up in Paper UI I found something interesting:

Exception in thread "Thread-39" java.lang.NoSuchMethodError: org.eclipse.smarthome.core.thing.binding.builder.ThingBuilder.withChannels(Ljava/util/List;)Lorg/eclipse/smarthome/core/thing/binding/builder/GenericThingBuilder;
        at org.openhab.binding.zigbee.handler.ZigBeeThingHandler.createChannelsFromDevice(ZigBeeThingHandler.java:162)
        at org.openhab.binding.zigbee.handler.ZigBeeThingHandler.initialize(ZigBeeThingHandler.java:96)
        at org.openhab.binding.zigbee.handler.ZigBeeCoordinatorHandler.browsingComplete(ZigBeeCoordinatorHandler.java:297)
        at org.openhab.binding.zigbee.handler.ZigBeeCoordinatorHandler$3.run(ZigBeeCoordinatorHandler.java:267

As I understand while running this thread (Runnable pollingRunnable in method initialize() for ZigBeeThingHandler class) a method is called which does not exist, but I can’t seem to find what could such a method be when calling ThingBuilder.WithChannels(channels).WithConfiguration(getConfig()) from ZigBeeThingHandler. This just adds channels and there configurations to a specific thing, all of which is done by ESH, so there should be no missing methods…

This exception is thrown after ZigbeeDiscoveryService started to create a ZigBee device with a bridge:


 20:49:29.749 [INFO ] [bee.discovery.ZigBeeDiscoveryService] - Creating ZigBee device zigbee:device with bridge zigbee:coordinator_cc2530:32a2b434

Could this mean that there is a method missing in my clusters? If no, do you have any idea what causes this exception and how to fix it? Thanks for your help!


Quick Edit: @Kai, after testing on an earlier OH2 version (not sure which one, it didnt have Build number, but it should be half a year old) I found that my channels showed up and were working perfectly, but testing the same bundle on OH2 Build: #448 resulted in my channels being ignored and not shown in PaperUI. Do you have any clue why this would be happening?

Quick note: I am using CC2530 Development Kit to test this binding.

Hey, everyone!

This is an updtate on my last post.

I have managed to work out my previous problem out a couple of weeks ago, just forgot to mention it here. The problem was a version mismatch, so I recompiled the binding against build #452 and tested it on various builds. Sadly, the same error occurs on earlier versions of OH2, but version from #452 seem to be just fine. And yes, this error was responsible for not letting me see the channels in PaperUI.

Is there a recommended Controller that works with this binding and raspbian?
Cheers

The current controller is the CC2531 from TI. This is a USB dongle so should work on the Pi. I know that Pine64 are looking at bringing out a controller with this chip - it will also be a USB dongle (I am testing this at the moment).

I’m also looking at a major overhaul of the binding to allow other dongles so hopefully in the coming few weeks I’ll have some news there. The hope is that other, more commercially available dongles, can also be employed - this is definately WIP though.

So you would expect any cc2531 will work?
Looks like a cheap Option:
http://m.ebay.de/itm/CC2531-zigbee-Sniffer-USB-dongle-Adapter-Ethereal-Protocol-Analysis-/261688726061?nav=SEARCH

?

To my knowledge the only controller that is Supported is CC2531, you can get this as a USB dongle from TI. I have tested it with BeagleBone Black on Debian, so it should work on Raspbian just as well. I think CC2530 Development Kit could work as a controller as well, but I havn’t tested that yet.

Seems like a PRC’s cheap knock off the real thing, but if it is identical to the real thing, then it should work. From my knowledge about China industry, they sometimes take rejected chips which they manufactured for the real distributor (in this case TI), and resell them for much cheaper or develop identical products like seemingly in this case. Usually they work perfectly fine, but there is no guarantee, so choose wisely!

In general, yes. The big problem with the 2531 is you need to make sure you program the right firmware, and there-in lies the problem. To program the firmware you need to get a programmer - the TI version is quite expensive (maybe 50 Euro I think - possibly a bit more) but I have seen some lower cost versions on eBay or Aliexpress.

The problem with the cheaper versions is there’s no way to know what firmware they use - if you can program the firmware, then they work fine (I’ve used them).

I have just bought a Telegesis dongle (arrived yesterday) which I’m planning to try and get working, but this will take some time yet.

1 Like

Thats some great news @chris! Quick note though, for me deserializeNode() method in ZigBeeNodeSerializer class always printed : Error deserializing from file: file does not exist message, to fix this I changed you relative path to /userdata/zigbee into an absolute path. I also changed a bit of deserializeNode() and serializeNode() methods. Here’s how the whole class looks:

public class ZigBeeNodeSerializer {
    private Logger logger = LoggerFactory.getLogger(ZigBeeNodeSerializer.class);
    private String folderName = "./userdata/zigbee";
    private File folder;

    private XStream createXStream() {
        final String USERDATA_DIR_PROG_ARGUMENT = "smarthome.userdata";
        final String eshUserDataFolder = System.getProperty(USERDATA_DIR_PROG_ARGUMENT);
        if (eshUserDataFolder != null) {
            folderName = eshUserDataFolder + "/zigbee";
        }

        folder = new File(folderName);

        // create path for serialization.
        if (!folder.exists()) {
            logger.debug("Creating directory {}", folderName);
            folder.mkdirs();
        }

        XStream stream = new XStream(new StaxDriver());

        stream.alias("Endpoint", ZigBeeEndpointImpl.class);
        stream.alias("Node", ZigBeeNodeImpl.class);
        stream.alias("NodeDescriptor", ZigBeeNodeDescriptor.class);
        stream.alias("PowerDescriptor", ZigBeeNodePowerDescriptor.class);
        stream.setClassLoader(ZigBeeEndpointImpl.class.getClassLoader());
        // stream.addImplicitCollection(ZigBeeNodeDescriptor.class, "macCapabilities");

        return stream;
    }

    public void serializeNode(ZigBeeApi zigbeeApi, ZigBeeNode node) {
        // Create a copy of the node for serialization
        ZigBeeNodeImpl node2 = new ZigBeeNodeImpl();
        node2.setIeeeAddress(node.getIeeeAddress());
        node2.setNetworkAddress(node.getNetworkAddress());
        node2.setNodeDescriptor(node.getNodeDescriptor());
        node2.setPowerDescriptor(node.getPowerDescriptor());

        final List<ZigBeeEndpoint> endpoints = new ArrayList<ZigBeeEndpoint>();
        for (final ZigBeeEndpoint endpoint : zigbeeApi.getNodeEndpoints(node)) {
            ZigBeeEndpointImpl endpoint2 = new ZigBeeEndpointImpl();
            endpoint2.setNode(node2);
            endpoint2.setDeviceTypeId(endpoint.getDeviceTypeId());
            endpoint2.setProfileId(endpoint.getProfileId());
            endpoint2.setDeviceVersion(endpoint.getDeviceVersion());
            endpoint2.setEndPointAddress(endpoint.getEndPointAddress());
            endpoint2.setInputClusters(endpoint.getInputClusters());
            endpoint2.setOutputClusters(endpoint.getOutputClusters());
            endpoint2.setEndpointId(endpoint.getEndpointId());

            endpoints.add(endpoint2);
        }

        final XStream stream = createXStream();

        // File file = new File(folder, node.getIeeeAddress().replace(":", "") + ".xml");
        File file = new File(folder, node.getIeeeAddress() + ".xml");
        BufferedWriter writer = null;

        try {
            writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"));
            stream.marshal(endpoints, new PrettyPrintWriter(writer));
            writer.flush();
        } catch (IOException e) {
            logger.error("{}: Error serializing network to file: {}", node.getIeeeAddress(), e.getMessage());
        } finally {
            if (writer != null) {
                try {
                    writer.close();
                } catch (IOException e) {
                }
            }
        }
    }

    @SuppressWarnings("unchecked")
    public List<ZigBeeEndpoint> deserializeNode(String address) {
        // address = address.replace(":", "");
        File file = null;
        BufferedReader reader = null;

        try {
            final XStream stream = createXStream();
            file = new File(folder, address + ".xml");

            logger.debug("{}: Deserializing from file: {}", address, file.getPath());

            if (!file.exists()) {
                logger.warn("{}: Error deserializing from file: file does not exist.", address);
                return null;
            }

            reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));

            Object xxx = stream.fromXML(reader);
            final List<ZigBeeEndpoint> endpoints = (List<ZigBeeEndpoint>) xxx;

            return endpoints;
        } catch (IOException e) {
            logger.error("{}: Error serializing from file: {}", address, e.getMessage());
        } catch (ConversionException e) {
            logger.error("{}: Error serializing from file: {}", address, e.getMessage());
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                }
            }
        }
        return null;
    }
}

Thought fixing the deserializeNode() method like this created double the amount of channels. And to fix that I had to remove coordinatorHandler.deserializeNode(nodeAddress); in ZigBeeThingHandler class, everything then runs just fine. As I understand deserializeNode() method is there to increase binding startup efficiency, but something goes wrong during that process and we end up with doubled channels. I haven’t yet check it out, but I wanted you to know this as well.

Sellers on aliexpress normally quickly answer stuff like that. I might contact a few to find an inexpensive source for the community…

What firmware specifially must be flashed ?

Cheers

I know that PINE64 guys intend to have something available very soon for around $25. I currently have some of their dongles at home.

Programmers are avilable quite cheap if you want to go down that route, and the firmware can be downloaded from TI…
http://www.aliexpress.com/store/product/ZIGBEE-emulator-debugger-for-CC1110-CC2530-SmartRF04EB-enterprise-edition/224898_971586481.html

You can indeed use the cheap ones. Be carefull though, there are ones that have the programming header available, and many others don’t. If they are not available you need to solder them on. The ones with header are not much more expensive.

Normally they come with the sniffer firmware not with the zigbee controller firmware.

On ebay there are also the cheap programmers, or you need to find someone that can do it for you (you need it only once)

Hi, I try to use the ZigBee binding. But as a newbee it is really hard to get started. I have a CC2531 USB board and a CC Debugger to flush the firmeware. But I have a couple of questions.

  1. Which firmware do I have to flush to the chip to make it work with the binding?
  2. How can I integrate the the binding in my Openhab installation? Do I have to build Openhab as a whole with the pullrequest merged or can I build the binding and add it as an jar?

Any hint in a direction would help a lot. Thank you very much.

Kenny

Hey Kenny, nice that someone is working on the binding. I haven’t worked
with Chris’s binding so I don’t know of he released the refactored version
yet, but I can answer your questions without a problem.

  1. You have to get the TI’s firmware from there website. A link has been
    given to it in one of my earlier posts about dongle in this discussion.

  2. Each binding in OH is a separate JAR file just as described by OSGi
    framework. So if you have an already compiled file, you just put it in
    addons folder and that’s it. If you want to compile or make modifications
    to Chris’s binding you must first get the whole OH project repository
    (there is a tutorial about this in OH2 docs) then get the Chris’s ZigBee
    binding project from git. It was a part of OH2’s addons project, if you
    search for ZigBee pull requests you will find the old code, but by now it
    should be an experimental binding and have it’s own repo. Once you have the
    project just import it into OH2 project structure, compile and export the
    ZigBee binding as a JAR.

Hope this helps and happy coding!

KPaul20005 Kenny Floria
October 7

Hi, I try to use the ZigBee binding. But as a newbee it is really hard to
get started. I have a CC2531 USB board and a CC Debugger to flush the
firmeware. But I have a couple of questions.

  1. Which firmware do I have to flush to the chip to make it work with the
    binding?
  2. How can I integrate the the binding in my Openhab installation? Do I
    have to build Openhab as a whole with the pullrequest merged or can I build
    the binding and add it as an jar?
1 Like

I’am also trying to get the zigbee binding to work, but I have this error when starting openhab:

org.osgi.framework.BundleException: The bundle class path entry “nrjavaserial-3.9.3.jar”

I’ve already tried to change the nrjavaserial version to 3.9.3 (which seams to be the current version in beta 4) but I still geht the error. How can I solve this? (I’ve already installed the openhab-transport-serial feature)