Zwave polling unlinked channels

I’m attempting to remove some noise from my zwave network due to performance problems and I’m currently looking at the polling associated with channels on smart plugs. Whenever I activate the switch on a smart plug, the binding appears to poll all channels associated with the Thing, even in the case when the channel is not linked to an Item. I might hope that the binding could be configured to not poll unlinked channels in order to reduce zwave network congestion. Is this the expected behavior and is there a way it can be managed other than creating a custom thing type without the channels? Thanks, any help is appreciated!

I asked a similar question on github a few weeks ago. Question on SET - GET and Command poll. · Issue #1904 · openhab/org.openhab.binding.zwave (github.com) I don’t recall when I thought I started to see this or whether it was always this way.

If your logs look the same, you could try to disable the command poll settings (1500 → 0). The “report” could be off with slow acting devices (dimmers), but otherwise it might work (with less traffic).

I remember there was some regression in this layer between OH 2.5 and 3.0 which affected zwave and other bindings, it started with this: removed ThingLinkManager and with it the auto-linking feature and "Simple Mode" by kaikreuzer · Pull Request #1385 · openhab/openhab-core · GitHub.

The framework behavior was not strictly defined prior this change. To be fair, it is still is not defined how many times channelLinked method of a thing handler should be called. Is it only upon very first creation of link, each creation of link (i.e. not called again when unlink/link cycle is made)? Maybe on each creation of a link, but also after framework restarts? The OH 2.5 behavior was like the last one, channelLinked method was called always when link channel was linked to an item, and always during “cycling” of these (unlink/linking again) letting binding rely on linkage status to poll data. Sadly it was decided to change which caused several bindings to suffer, zwave including. There is still discussion of what to do with linking: https://github.com/openhab/openhab-core/issues/1707 (be aware, this discussion is over 3 year old).

If you look at last link there was fix for that in 2020 which should address this issue with zwave binding, but it could be that you just found a severe bug.

Thanks for the link. This (what OP noted) could have been going on since OH3.0. I found what was added to the zwave binding.

            // if the channel is already linked, add it to our list of channels to poll for
            if (isLinked(channel.getUID().getId())) {
                thingChannelsPoll.add(channel.getUID());
            }

My java skill is limited (and I don’t quite understand channelLinked works ), but it looks like it was intended to poll on startup (initialization) but there is also a section under that heading that might get picked up when commands are issued (again not sure).

        // Create the channels list to simplify processing incoming events
        thingChannelsCmd = new ArrayList<ZWaveThingChannel>();
        thingChannelsState = new ArrayList<ZWaveThingChannel>();
        for (Channel channel : getThing().getChannels()) {
            logger.trace("NODE {}: Processing channel: {} == {}", nodeId, channel.getUID(),
                    channel.getChannelTypeUID());

I could add a log element for testing to see if this is related to the above problem, but I have don’t have a system to test with “command”-able Nodes right now (just a small WSL test with battery sensors) as I have been testing the MQTT based Zwave-JS-UI with OH4. Will have to wait until @chris gets a chance to comment.

Thanks for all of the replies. I’ve done some additional testing and can confirm that setting Command Poll Period to 0 does stop the polling after sending a command. This helps with the meter channels but leaves the switch channel un-polled. This is probably fine for a workaround, thanks for the suggestion apella12.

I still don’t fully understand when this occurs and when it doesn’t. Are we saying that if you add a net new device and never link a channel for the meter channels, that it will never poll. But if you add a device, link a meter channel, then unlink the channel, that it will continue to poll the unlinked channel?

I intend to test this myself but got caught up in another issue which is slowing me down related to initialization. Zwave device initialization failing after restart - Add-ons / Bindings - openHAB Community . This other issue is causing a problem because I can’t poll a device that’s not yet initialized, so my devices to test on are limited right now.

Although not according to spec, some switches will send a report after getting a SET command, but if your switch state is not getting updated, then the poll is necessary if you need that information. Possible idea could be to put the controller in the switch’s Basic set Association group. Sometimes that updates the switch state in OH without a poll.

As noted I can’t say I do either. However, your observation that “0” disables the command poll is instructive. That narrows it down to why channels unrelated to the command channel are polled?

I don’t know the answer to either question at this point.

With OH prior 3.0 thing handler (binding implementation) was notified about links in a specific way through channelLinked method. It was a signal to binding that there is item which need to be feed with data from given channel, so binding could decide to do something about that. For radio or battery based devices it is essential to optimize readouts and ignore channels which are known, but not needed by anyone.
This is essentially issue you see now with polling of unwanted channels. Thing is - there is condition which tracks state channels with linked channels: https://github.com/openhab/org.openhab.binding.zwave/blob/main/src/main/java/org/openhab/binding/zwave/handler/ZWaveThingHandler.java#L395C39-L395C39.

If you consider going deeper into what’s going on consider debugging above code fragment first, because that’s where linked channels are validated prior polling their state. Don’t worry much about knowing or not Java syntax, as long as you just manipulate code and glue text its gonna work. I recently did similar try-fail updates with .net project built and running under linux. :smiley: Good luck!

Ran tests today in my test bed OH4.1 (docker) on WSL Debian with 2 battery devices using the REFRESH command. Not “Command poll”, but it uses the same code AFAICT.

TLDR: no unlinked channels were polled but all linked channels are polled.I’m going to close my issue on github. Log there was from a third party and I don’t know what was linked and what wasn’t.

  1. Startup: None of the five available device channels linked to items.
  2. Linked one channel to an item
    2024-01-03 10:25:23.508 [DEBUG] [ding.zwave.handler.ZWaveThingHandler] - NODE 2: Channel zwave:device:3a039ad75c:node2:sensor_luminance linked - polling started.
  3. Wrote Refresh switch snippet
rule "Refresh Node2"
when 
    Item Refresh_Node2 changed to ON
then
    ZWave_Node_002_DMMS1_Dome_ZWave_Plus_Motion_Detector_with_Light_Sensor_and_Flexible_Magnetic_Mount_Sensor_luminance.sendCommand ("REFRESH")
end
  1. Ran refresh with only that item polled
2024-01-03 10:43:15.962 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'ZWave_Node_002_DMMS1_Dome_ZWave_Plus_Motion_Detector_with_Light_Sensor_and_Flexible_Magnetic_Mount_Sensor_luminance' received command REFRESH
2024-01-03 10:43:15.966 [DEBUG] [ding.zwave.handler.ZWaveThingHandler] - NODE 2: Command received zwave:device:3a039ad75c:node2:sensor_luminance --> REFRESH [RefreshType]
  1. Woke device to send GET message and state updated.

  2. Unlinked item (No linked items)
    2024-01-03 10:53:23.364 [DEBUG] [ding.zwave.handler.ZWaveThingHandler] - NODE 2: Channel zwave:device:3a039ad75c:node2:sensor_luminance unlinked - polling stopped.

  3. Ran refresh (No ZW debug entry)
    2024-01-03 10:55:32.601 [INFO ] [openhab.event.ItemCommandEvent ] - Item 'ZWave_Node_002_DMMS1_Dome_ZWave_Plus_Motion_Detector_with_Light_Sensor_and_Flexible_Magnetic_Mount_Sensor_luminance' received command REFRESH

  4. Woke device & No poll

  5. Linked again, plus Battery channel

2024-01-03 11:04:12.607 [DEBUG] [ding.zwave.handler.ZWaveThingHandler] - NODE 2: Channel zwave:device:3a039ad75c:node2:sensor_luminance linked - polling started.
2024-01-03 11:04:43.689 [DEBUG] [ding.zwave.handler.ZWaveThingHandler] - NODE 2: Channel zwave:device:3a039ad75c:node2:battery-level linked - polling started.
  1. Ran refresh
2024-01-03 11:05:30.699 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'ZWave_Node_002_DMMS1_Dome_ZWave_Plus_Motion_Detector_with_Light_Sensor_and_Flexible_Magnetic_Mount_Sensor_luminance' received command REFRESH
2024-01-03 11:05:30.705 [DEBUG] [ding.zwave.handler.ZWaveThingHandler] - NODE 2: Command received zwave:device:3a039ad75c:node2:sensor_luminance --> REFRESH [RefreshType]
  1. Woke device and both linked channels were polled.
1 Like

Thank you all for the feedback and apella12 for doing that testing. I’ve been troubleshooting general z-wave performance issues which are impacting my ability to spend much time on this polling issue, but in due time I’ll consider the advice offered here and update the thread. Thanks!

1 Like

I did some additional work on my problem today and made some progress. I started by running a REFRESH, it polled the unlinked channels. I linked/unlinked the channel many times in many ways, did a REFRESH, it still polled.

During every link / unlink, the logs were consistently showing the “polling started” message and never showing the “polling stopped” message from ZWaveThingHandler:

The ChannelLinkNotifier was not notifying the ZWaveThingHandler that the channel was removed because line 80 here was returning true:

The ItemChannelLinkRegistry has 3 isLinked() functions that take a (ChannelUID), (Item String, ChannelUID), and (Item String). The first of those 3, which is the one that the ChannelLinkNotifier uses was returning true whereas the two others returned false. But getLinkedItems would return an empty set:

I tried removing the link through the GUI, the Developer API, and more direct ways with no luck. Then I found ItemChannelLinkRegistry.removeLinksForThing() and that worked like a charm. Then I proceeded to test as apella12 specified above and got the exact same result he got. It doesn’t poll unlinked channels. When I add a channel, it polls, when I remove it then it stops polling. I’m also getting the debug message from the ZWaveThingHandler “polling stopped”.

My conclusion is that there is some preexisting data anomaly causing the ItemChannelLinkRegistry or its parent AbstractRegistry to fail on the isLinked() call. I suppose I might be able to figure that out with enough work. I assume these data are on disk somewhere, perhaps jsondb/*ItemChannelLink.json.

I also need to figure out how to clean up the remainder of these issues in my instance. I noticed a very promising and scary looking function called ItemChannelLinkRegistry.purge() which purports to “Remove all orphaned links”. If I was confident in my backups, I might just try that…

1 Like

I confirmed in a backup ItemChannelLink json file that the links are there in the backup. I suppose this means that the deletion and/or detection of the links is where the breakdown is and that the one isLinked() call is correct, the two are wrong, but the GUI cannot find those links.

I confirmed that the ItemChannelLink json file had a link to an Item that had been previously been deleted. If I created a new item with the exact same name it would automatically already be linked to the channel and I could unlink it successfully.

That was a pain so I used the API Explorer which had an endpoint to do the purge /links/purge. The purge deleted 23 of these and this issue is solved for me. It appears that this issue was not related to Zwave in the end but rather related to these orphaned links. Thanks all who assisted.

It appears that rlkoshak provides information on how to detect and remove orphaned links in this prior thread: OH3 Broken links on items after upgrade from 2.5.10 - Setup, Configuration and Use / Migration - openHAB Community . I did not confirm this would have worked for me, but it seems likely, would have gotten me there hours earlier, and seems a better way to do it.

Quoting rlkoshak:

From the Karaf console run

openhab:links orphan list

will show all the broken links and

openhab:links orphan purge

will delete them all.

4 Likes

It could be that changes in how internal store worked in OH 2.x and 3.x takes an effect now. I saw just couple of weeks ago someone who conducted migration from 2.x to 4.1 and experienced some issues with stored thing/channel definitions. Obviously such long gap have not been tested by anyone so far.

As for possible causation of issue - the orphaned channel UID points to a thing, but does not specify channel type (as far I can see). I can think of situation that channel identifiers been changed and thing identifiers been retained, leading to situation that there are no channel instances reflected in real device. The zwave handler is notified about linking of unknown channels, which it then blindly poll issuing radio calls. Does it sound reasonable?
I think this is essentially what you have confirmed with channel linked call statements (note I am not a zwave guy, I just happen to know history of related code within core).

I did look through the Z-Wave device database history to determine if the channel name had changed at any point throughout history and it was not the case in the device I looked at. The channel name was ok in the link record, but the Item it referred to was gone. The thread that rlkoshak commented in above indicated that in earlier versions of OH, that orphaned links occurred more often and less often now. I saw another thread where there was a suggestion that this could even be desirable behavior in some cases as it might allow someone to do maintenance easier.

I might argue that there is a bug in the ItemChannelLinkRegistry in that the three forms of isLinked() return different results when looking at an orphaned link. One might argue that orphaned links are themselves the problem. I would think all three function calls should return the same value. I saw some other discussion from years ago that suggested that orphaned links are “ok” because they don’t really do much harm. Fair enough, this might not be “much” harm and likely wasn’t a known side effect at the time.

I believe that this should be indeed consistent across calls. The orphaned status might vary depending on bootstrap stage, however once system is warmed up, all configs are loaded, they are configuration errors. As for now some of these orphans are visible in UI if you click through items. If your items are gone and you have links with them, there is no UI which can help with the problem.