LightwaveRF Binding Updated

Just uploaded a new version (1.0.4) that stops discovery of already added devices.

Looks good, nothing coming up now, Iā€™ll remove something from my things file just to test it comes back though :slight_smile:

damn forgot to alter your battery multiplier, give me 5.

Yep, that worked, it doesnā€™t remove them from the inbox, but if I remove them they donā€™t come back, unless I remove from my things file, and then it comes back.

Good work!

@xela just uploaded new (1.0.5) - let me know it works (battery level fix)

For any new issues relating to v2 binding please use the new thread from now on
Have submitted a pull request for the binding, lets see how bad my coding skills are :slight_smile:

Unfortunately not, and this came up in the log that looks related

18:35:44.912 [WARN ] [ommon.WrappedScheduledExecutorService] - Scheduled runnable ended with an exception:
java.lang.IllegalArgumentException: Value must be between 0 and 100
        at org.eclipse.smarthome.core.library.types.PercentType.validateValue(PercentType.java:57) ~[?:?]
        at org.eclipse.smarthome.core.library.types.PercentType.<init>(PercentType.java:42) ~[?:?]
        at org.openhab.binding.lightwaverf.internal.handler.DeviceHandler.updateChannels(DeviceHandler.java:360) ~[?:?]
        at org.openhab.binding.lightwaverf.internal.handler.DeviceHandler.updateChannels(DeviceHandler.java:317) ~[?:?]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[?:1.8.0_232]
        at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) ~[?:1.8.0_232]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) ~[?:1.8.0_232]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) ~[?:1.8.0_232]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_232]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_232]
        at java.lang.Thread.run(Thread.java:748) [?:1.8.0_232]

Ok, just trying to fix a build problem and Iā€™ll have a look
Use 1.0.4 for now

Got almost the whole house on the binding now. The few devices left in the script polling are hitting Structure Not Found 80% of the time now, probably becuase Iā€™m polling extra stuff in the binding that I didnā€™t poll for before (rgbColor, identify and protection).
Will the binding output an WARN if it gets a response failure / structure not found back from LWRF? Or is there some other way I can monitor how well itā€™s doing under the hood?

UPDATE
Yes, Iā€™ve hit the limit. Iā€™ve added another device and now the binding isnā€™t seeing status updates from the existing ones

if you have left at the default settings you shouldnt get any structure not founds.
default is 5 seconds - 20 items.
so if you have 21-40 items will poll 20,5 second gap, poll 1-20 items, 5 second gap (so 10 second loop)
41-60 items - 15 second loopā€¦
see where this is going?
you can increase though, 30 items was the optimal, there was no speed increase above this.

Just uploaded 1.0.6, should have fixed battery level

How many devices are you polling on the binding?
How many are you polling on the script?
Also I remember you saying you split the script in 2, so are there 2 scripts and the binding running?
Change log level to debug and youā€™ll see whatā€™s happening under the hood as will give you the json response. Pm them to me

Working!

Will move to new thread now

1 Like

Right Iā€™ve turned off the old script polling altogether and rebooted and the binding is posting item statuses in the log again now.
As of right now Iā€™m polling for 95 items/statuses and to run the whole house Iā€™ve got to add about another 20
Control of things with the binding seems to be responsive, no more than a second from doing something in the sitemap to it happening in the house. Updates are a bit variable though, for example I just turned on a light and the switch mimic updated almost at once but it took 11 seconds for the power consumption value to update. Dimlevel changes can also be a bit hit and miss.

If you have 95 items itā€™s going to take up to 25 seconds if you have left at the defaults:
95 / 20 = (rounded up to 20) 5 * 5 second poll interval = 25 seconds

Unfortunately until lightwave sort their api out thereā€™s nout I can do.
You can experiment with the settings under the account though (just watch your logs that your getting the response within the refresh interval time though, donā€™t want it to overrun, next poll start and they all end up queueing as this will bog the system down)

But sending commands will be literally instantaneous

If you turn on debug and watch the responses you will see the groups of different featureIds, youā€™ll then be able to make sure that it responds within the poll period. I think for 50 items at once it was no quicker than 6 seconds back from lightwave, so therefore keep your polling time to say 8 seconds.
then 115(items) / 50 rounded (3) * 8 = 24 seconds loop.
Maybe use 40 items @ 6 seconds = 18 second loop

I will eventually add in some rate messages to let you know your trying to go too fast.
Oh and when testing I also foundā€¦ if I requested once it would take 6 seconds, if I hit it twice and more the response time would drop, so lightwave do have some form of caching going on

And Iā€™ve still got to sync updates/commands at present. Need a small break though to get some real work done :joy:

Yeah, its the old issue with the rate limit on the API, I understand that.
The binding is a big improvement though because it spreads the polls out and everything gets returned, albeit some a little later than others. With the script approach at my level of load the only way I could get it to poll properly was to do it every 30 seconds and leave out everything that wasnā€™t absolutely necessaryā€¦ Even then I still used to get the occasional Structure Not Found and that meant no data at all until the next successful cycle.
Iā€™m going to add the final items in tomorrow and report back once itā€™s running the whole house.

The script became useless in the end for me due to the amount of items I have.
Bear in mind, the binding opens up a new thread for the polling - I did initially open a thread for each thing but it broke the system.
Depending on what other stuff you have (I have 4 other bindings that use additional threads) you may need to up your safecall threads in the cfg. See how it goes though. I know itā€™s 3 threads for rules, canā€™t remember if itā€™s 3 or 5 for safecall (bindings)

Hello Dave,
Iā€™m using 2.5 stable and i have just installed the binding and i get " Status: UNINITIALIZED - HANDLER_INITIALIZING_ERROR java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $ "

2020-02-12 19:27:15.933 [ERROR] [nal.common.AbstractInvocationHandler] - An error occurred while calling method ā€˜ThingHandler.initialize()ā€™ on ā€˜org.openhab.binding.lightwaverf.internal.handler.LWAccountHandler@192c816ā€™: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:224) ~[bundleFile:?]
at com.google.gson.Gson.fromJson(Gson.java:888) ~[bundleFile:?]
at com.google.gson.Gson.fromJson(Gson.java:853) ~[bundleFile:?]
at com.google.gson.Gson.fromJson(Gson.java:802) ~[bundleFile:?]
at com.google.gson.Gson.fromJson(Gson.java:774) ~[bundleFile:?]
at org.openhab.binding.lightwaverf.internal.UpdateListener.login(UpdateListener.java:159) ~[?:?]
at org.openhab.binding.lightwaverf.internal.handler.LWAccountHandler.initialize(LWAccountHandler.java:77) ~[?:?]
at sun.reflect.GeneratedMethodAccessor73.invoke(Unknown Source) ~[?:?]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_232]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_232]
at org.eclipse.smarthome.core.internal.common.AbstractInvocationHandler.invokeDirect(AbstractInvocationHandler.java:152) [bundleFile:?]
at org.eclipse.smarthome.core.internal.common.Invocation.call(Invocation.java:52) [bundleFile:?]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_232]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_232]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_232]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_232]
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:385) ~[bundleFile:?]
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:213) ~[bundleFile:?]
ā€¦ 15 more
2020-02-12 19:27:15.977 [ERROR] [core.thing.internal.ThingManagerImpl] - Exception occurred while initializing handler of thing ā€˜lightwaverf:lightwaverfaccount:penthomeā€™: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:224) ~[bundleFile:?]
at com.google.gson.Gson.fromJson(Gson.java:888) ~[bundleFile:?]
at com.google.gson.Gson.fromJson(Gson.java:853) ~[bundleFile:?]
at com.google.gson.Gson.fromJson(Gson.java:802) ~[bundleFile:?]
at com.google.gson.Gson.fromJson(Gson.java:774) ~[bundleFile:?]
at org.openhab.binding.lightwaverf.internal.UpdateListener.login(UpdateListener.java:159) ~[?:?]
at org.openhab.binding.lightwaverf.internal.handler.LWAccountHandler.initialize(LWAccountHandler.java:77) ~[?:?]
at sun.reflect.GeneratedMethodAccessor73.invoke(Unknown Source) ~[?:?]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_232]
at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_232]
at org.eclipse.smarthome.core.internal.common.AbstractInvocationHandler.invokeDirect(AbstractInvocationHandler.java:152) [bundleFile:?]
at org.eclipse.smarthome.core.internal.common.Invocation.call(Invocation.java:52) [bundleFile:?]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_232]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_232]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_232]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_232]
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 1 path $
at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:385) ~[bundleFile:?]
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:213) ~[bundleFile:?]
ā€¦ 15 more

Sorry i just realized that iā€™m running on docker and the root ca are not installed :slight_smile: is it possible to add an option to disable ssl verification ? On the script based version of lightwaverf i had to modify manualy and add the ā€œ-kā€ option on curl

you got the latest version from git?
I have literally just uploaded a new version 1.0.7 (deleted old ones too so no one gets wrong one)

Version 1.0.7

  • Fixed bug with Update listener not reflecting the correct polling time
  • Removed Update Listener additional Thread as was unstable
  • Added synchronization lock for handle command - status will now stay in sync.

@xela @Fixer