Upgrade from 2.1 to 2.4: Handler not called anymore

Hello,

I just upgraded my OpenHAB server from 2.1 to 2.4 and after fighting quite a few obstacles, I got my binding compiling again. But after I deployed the new version, I cannot control my house anymore: My Handler’s handleCommand(…) is not called at all (nothing in the log).

When I switch the lights using a classic light switch, the BasicUI is updated and shows the new dimmer states immediately. The Android app is not immediately updating, but if I “leave” and “re-enter” the room in the Android app, it shows the new state.

However, changing the dimmer states in the BasicUI and the Android app both does not work anymore, at all :frowning:

I’ll still have to do some more debugging, but I have to say again that working with OpenHAB is a nightmare! If there was another free Java-based solution available, I’d definitely switch! Every time, I want to change a small thing in my binding, I have to spend at least a day to get everything running, again. This is really inacceptable!

Marco.

What binding is this about?

1 Like

I just started it from/within Eclipse – with my productive configuration copied into the distro-resources. My HandlerFactory’s createHandler(…) method is invoked correctly (for quite a few thing instances – my house is large :wink: ). Then, the Handler’s initializeChannel(…) method is called fine, too (also quite many threads hit the breakpoint there simultaneously, because I have heaps of items – only the lights alone are already 80 items in the house :wink: ).

But if I open the BasicUI and change a dimmer value, absolutely nothing happens!

This is the problem:

2018-12-29 18:58:04.828 [DEBUG] [.e.s.i.r.c.i.item.ItemResource:380  ] - Received HTTP POST request at 'items/Room05_Light0' with value '48'.
2018-12-29 18:58:04.829 [INFO ] [arthome.event.ItemCommandEvent:53   ] - Item 'Room05_Light0' received command 48
2018-12-29 18:58:04.829 [INFO ] [.event.ItemStatePredictedEvent:53   ] - Room05_Light0 predicted to become 0
2018-12-29 18:58:04.829 [DEBUG] [e.s.c.t.i.CommunicationManager:335  ] - Received  event '48' for non-existing channel 'intellihouse:dimmer:host040:laundryLight0', not forwarding it to the handler

WTF?!??? The channel DOES exist!!! Why does he think the channel does not exist?

What do I have to do to tell him that the channel does exist besides from naming it in the items file? And please do not tell me that I have to declare my items’ possible channels in the source code. They are dynamic! Every thing can have an arbitrary number of channels, because that depends on the configuration of the raspberry pi.

Here’re some example lines from my items file:

Dimmer Room31_LightAll               "Light All"  (Room31, Lights)  {channel = "intellihouse:dimmer:host310:officeLightController"}
Dimmer Room31_Light0                 "Light 0"  (Room31, Lights)  {channel = "intellihouse:dimmer:host310:officeLight0"}
Dimmer Room31_Light1                 "Light 1"  (Room31, Lights)  {channel = "intellihouse:dimmer:host310:officeLight1"}

As you can see the items file maps a host (a raspberry pi) and a bean in its spring context.

I now added the following 2 lines to initializeChannel(...) to make sure that the channel is clearly marked as existing:

updateStatus(ThingStatus.ONLINE);
updateState(channelUID, new PercentType(100));

=> No effect.

Just to prevent misunderstandings: The initializeChannel(...) is invoked! My break-point there was clearly hit.

IMHO this is clearly a bug in OpenHAB!

  1. It worked fine with OpenHAB 2.0 and 2.1.
  2. If OpenHAB thought – for whatever reason – that this channel would not exist, why does it call initializeChannel(...) for it?

Please fix this bug quickly!

I traced the problem further:

org.eclipse.smarthome.core.thing.internal.CommunicationManager.handleEvent(String, T, String, Function<String, List<Class<? extends T>>>, ProfileAction<T>)

In this method, the method thing.getChannel(channelUID.getId()); is called. This returns null. I have no idea, how this was different before, i.e. if the channels were added dynamically to my things or if the CommunicationManager did not care, but definitely, this is wrong, now.

I’ll try, if I can somehow lazily add Channel instances programmatically. Maybe inside this Handler.initializeChannel(...) method. If you have any good suggestions, please let me know!

Thing.getChannels() is immutable :angry:

What is the proper way to dynamically add channels?

It seems I found it. Currently trying…

@nlmarco

What happens when you use karaf console:

smarthome:links list

or

smarthome:links list | grep Room05_Light0

If second command has an empty result, then try:

smarthome:inbox list

If third command has an empty result, then try:

smarthome:inbox listignored

if fourth command has an empty result, then, sorry, I don’t know.

You also can check, if this parameter is set to “ON”. “Auto Approve”

You can edit a thing via editThing() and with ChannelBuilder add channels. I’m not behind a computer so it’s a little bit hard to give a precise answer. But search for editThing in the openhab2-addons repo to get some usage examples. Hope this helps a little.

Thank you very much!!! I got it running! It now seems to be working fine. I only noticed that the Android app isn’t immediately updated anymore (this worked with OpenHAB 2.1), but this is not so important – definitely no show-stopper.

I wanted to integrate my solar (PV) system. But now, the entire day is gone making my downstream-project functional again and being able to develop. I really hope OpenHAB improves/replaces the build system very soon.

Look, it is totally fine that the behaviour of a framework changes from one version to another. But it is absolutely unprofessional to force downstream projects to always work based on git master. When I want to fix a little bug in my own project, I really don’t have time to spend a whole day to get OpenHAB and my project compiling again.

OpenHAB has a nice and clean code base. This is professional. But the handling of builds, releases and downstream-projects is a catastrophe. And everytime I have to touch it, I get nightmares, because I’m forced to burn time for things I do not want to do! I wanted to integrate my PV system – I did not want to upgrade from OpenHAB 2.1 to 2.4 or even 2.5-SNAPSHOT. But I was forced to (I currently compile against 2.5.0-SNAPSHOT, but fortunately my JARs still work on 2.4, as well – so I can at least run a stable release on my productive server).

So, again THANKS for your help! But please please please do sth. about the build environment and its unnecessary burning of heaps of time!

:+1:

May I ask what your solution is?

My solution is to dynamically add all channels during the invocation of Handler.initialize() and inside a RegistryChangeListener, which I also register in Handler.initialize() via linkRegistry.addRegistryChangeListener(...).

linkRegistry is an instance of ItemChannelLinkRegistry, which I obtain using a ServiceTracker.

The code registering each channel looks like this:

protected void registerChannelIfNeeded(final ChannelUID channelUID) {
    requireNonNull(channelUID, "channelUID");
    final Thing thing = getThing();
    synchronized (thing) {
        List<Channel> channels = new ArrayList<>(thing.getChannels());
        for (Channel channel : channels) {
            if (channelUID.equals(channel.getUID())) {
                logger.info("registerChannelIfNeeded: thingUid={}: Channel already existing (skip): {}", thing.getUID(), channelUID);
                return;
            }
        }
        logger.info("registerChannelIfNeeded: thingUid={}: Registering channel: {}", thing.getUID(), channelUID);
        ThingBuilder thingBuilder = editThing();
        ChannelBuilder channelBuilder = ChannelBuilder.create(channelUID, getAcceptedItemType());
        channels.add(channelBuilder.build());
        thingBuilder.withChannels(channels);
        updateThing(thingBuilder.build());
        logger.info("registerChannelIfNeeded: thingUid={}: Channels: {}", thing.getUID(), toChannelUidStringList(thing.getChannels()));
    }
}

This code is not very efficient – iterating the channel-list – but since this happens only once during startup and there are very few channels per thing (maybe about 10), this is totally fine and does not justify more complex code.

In case, you would like to take a look at the sources, here’s the GitHub-repo: intellihouse

The actual OpenHAB-binding is in the (sub)project house.intelli/org.openhab.binding.intellihouse.

1 Like