Binding Request: Nanoleaf Aurora (LED Design Triangle)

Hi Martin,
I installed your binding for my Nanoleaf Aurora yesterday and came across some interesting an disturbing issue. Binding installs ok, discovery works fine even the authorisation token is granted and included in the thing definition. Afterwards it gets weird: The bridge thing comes online, just to go offline immediately. Even with the bridge thing being marked offline, discovery of the panels works fine, they all show up in Paper UI’s inbox als well in Habmin’s inbox. When going offline, the bridge thing’s status reads “Laufzeitfehler. Siehe openHAB Logdatei für mehr Details.” - “runtime error. please see openhab log for details”. openhab.log contains the following error message, repeating every 15 seconds, which equals to the defined refresh interval:

2019-02-28 08:42:02.074 [WARN ] [al.handler.NanoleafControllerHandler] - Update job failed
java.lang.NullPointerException: null
at org.openhab.binding.nanoleaf.internal.handler.NanoleafControllerHandler.updateFromControllerInfo(NanoleafControllerHandler.java:472) ~[?:?]
at org.openhab.binding.nanoleaf.internal.handler.NanoleafControllerHandler.runUpdate(NanoleafControllerHandler.java:338) ~[?:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:?]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [?:?]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [?:?]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [?:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:?]
at java.lang.Thread.run(Thread.java:748) [?:?]
2019-02-28 08:45:03.046 [WARN ] [al.handler.NanoleafControllerHandler] - Update job failed
java.lang.NullPointerException: null
at org.openhab.binding.nanoleaf.internal.handler.NanoleafControllerHandler.updateFromControllerInfo(NanoleafControllerHandler.java:472) ~[?:?]
at org.openhab.binding.nanoleaf.internal.handler.NanoleafControllerHandler.runUpdate(NanoleafControllerHandler.java:338) ~[?:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:?]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [?:?]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [?:?]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [?:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:?]
at java.lang.Thread.run(Thread.java:748) [?:?]
2019-02-28 08:45:18.161 [WARN ] [al.handler.NanoleafControllerHandler] - Update job failed
java.lang.NullPointerException: null
at org.openhab.binding.nanoleaf.internal.handler.NanoleafControllerHandler.updateFromControllerInfo(NanoleafControllerHandler.java:472) ~[?:?]
at org.openhab.binding.nanoleaf.internal.handler.NanoleafControllerHandler.runUpdate(NanoleafControllerHandler.java:338) ~[?:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:?]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [?:?]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [?:?]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [?:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:?]
at java.lang.Thread.run(Thread.java:748) [?:?]

The Nanoleaf bridge thing is autodiscovered, haven’t defined any items yet. Does this give you any hint on the problem?

Best regards
Kai

Hi Martin.
I have tested the binding now again and i have the same problem like Kai.
Greetings,
Markus

Hi Kai, Markus,

this is actually weird! I’ve restarted the setup from scratch to see if I can reconstruct this error. Here is what I did:

  • In Karaf console, stopped the binding with bundle:stop <id>
  • Deleted the binding jar from /usr/share/openhab2/addons
  • Removed any Nanoleaf .things and .items files
  • Downloaded the current JAR from the bridge branch
  • Copied the JAR to /usr/share/openhab2/addons folder
  • In Karaf, the binding now appears as follows:

Active │ 80 │ 2.5.0.201902231511 │ Nanoleaf Binding

  • In PaperUI, start a scan from the inbox with the newly installed Nanoleaf Binding → The controller is added as a new entry with name Light Panels <6-digit hex id, e.g. 12:e8:d5>
  • Added the controller to my things → Status of the controller thing is now OFFLINE - CONFIGURATION_PENDING No authorization token found. To start pairing, press the on-off button of the controller for 5-7 seconds until the LED starts flashing in a pattern.
  • After pressing the button, the controller turns to state ONLINE (and stays there)
  • Going back to the inbox, starting another scan for the Nanoleaf binding → all connected panels are added as new entries with name Light Panel
  • Added them to my things → Status of the controller and added panels is ONLINE (and stays there)

I could not notice that the state of the controller changed to OFFLINE once it became ONLINE after pairing.

I’ve tested the process above on a 2.3, 2.4 and current 2.5 OH instance.

From the stacktrace, it looks to me that it may come from an older version of the binding/Jar, as it seems unlikely that a NullPointer is thrown at this line (although not impossible).

Can you check in Karaf if you are on the same version that I am?

Thanks and Greetings
Martin

Hi Martin,
thanks for the reply, here’s what I’ve checked. First - current binding’s version is the same as yours:

Active │ 80 │ 2.5.0.201902231511 │ Nanoleaf Binding
Me setup is an Openhab2 Installation on a docker image. Docker host is running docker 18-06.ce-1 on Raspbian stretch. I went through the steps:

  • Stop binding in Karaf console with “bundle: stop
  • Deleted the binding jar from openhab2/addons directory (docker container bind mounts this directory from host
  • deleted the unused Aurora thing from Inbox
  • deleted nanoleaf items
  • no nanoleaf things were present
  • downloaded the current JAR from the bridge branch by “wget https://github.com/raepple/nanoleaf-binding/raw/bridge/target/org.openhab.binding.nanoleaf-2.5.0-SNAPSHOT.jar
  • chowned the downloaded JAR to the openhab service user, the container is running as
  • copied the downloaded JAR to the openhab2/addons directory. This gives the log line in openhab.log: 2019-03-02 22:00:14.468 [INFO ] [g.discovery.internal.PersistentInbox] - Added new thing 'nanoleaf:controller:############' to inbox.
  • Added the controller to my things by autodiscovery in Paper UI, name is Aurora <6-digit-hex id>, Status is OFFLINE - CONFIGURATION_PENDING No authorization token found. To start pairing, press the on-off button of the controller for 5-7 seconds until the LED starts flashing in a pattern. Only difference is my status is displayed in german.
  • Go downstairs, start pairing by pressing the on-off button as described
  • Go upstairs to find the Nanoleaf Controller thing marked as OFFLINE - Runtime error. See openHAB log for more details.

openhab.log gives the following log messages, repeating every 60 seconds which is the default refresh rate:
2019-03-02 22:07:34.631 [WARN ] [al.handler.NanoleafControllerHandler] - Update job failed java.lang.NullPointerException: null at org.openhab.binding.nanoleaf.internal.handler.NanoleafControllerHandler.updateFromControllerInfo(Nanoleaf ControllerHandler.java:472) ~[?:?] at org.openhab.binding.nanoleaf.internal.handler.NanoleafControllerHandler.runUpdate(NanoleafControllerHandl er.java:338) ~[?:?] at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:?] at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [?:?] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecut or.java:180) [?:?] at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java :294) [?:?] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:?] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:?] at java.lang.Thread.run(Thread.java:748) [?:?]
Never mind the line breaks :roll_eyes: Karaf console says:
Active │ 80 │ 2.5.0.201902231511 │ Nanoleaf Binding
So it’s the same version as before. Java version is:
openjdk version "1.8.0_192" OpenJDK Runtime Environment (Zulu 8.33.0.134-linux_aarch32hf) (build 1.8.0_192-b134) OpenJDK Client VM (Zulu 8.33.0.134-linux_aarch32hf) (build 25.192-b134, mixed mode, Evaluation)
Is there anything else I can try?
Thanks and greetings
Kai

Hi Kai,

does your Nanoleaf Aurora has the Rhythm module connected to it? I have the so-called Nanoleaf Light Panels Rhythm Starter Kit, which came with the Ryhthm module. The reason I am asking is because the NullPointer is thrown where the data about the connection state of the Rhythm module is queried from the information returned by the controller.

I just switched to docker with my OH instance as well, but still find the Nanoleaf controller and all panels in ONLINE state.

I usually try to avoid discovery of all the things in my home, and have everything setup in files. Have you tried that as well? To find out your current authorization token (which is not shown in clear text in the Paper UI) for the file-based thing configuration, you can send a GET request to http(s)://openhab-ip:port/rest/things, and search in the response for “authToken”. You can also generate a new token yourself by pressing the button on the controller for 5 seconds, and then send a POST request (e.g. with Postman) to http://nanoleaf-ip:port/api/vi/new. This will return a new token in the response (note that when you remove the controller thing, the binding removes the token from the controller as well).

Greetings
Martin

Hi Martin.
I don’t have the Ryhthm module. My system is running on Ubuntu 16.04, Intel NUC.
My actual setup uses the file system. I use scripts to get the information from the controller and send them back. This works very well but is not nice.
Is it a problem, that the controller has to work with 2 token at the same time?
Greetings,
Markus

Hi Martin,
No, my Aurora doesn’t have the rythm module. I try to avoid those autodiscoveries as far as I can, too. I think I have tried setting it up in the thing file earlier . To make sure, I will start another try from scratch. Just like Martin has, I adress the Nanoleaf with a script that does some time based actions on the Nanoleaf. This script uses an authorization token that definitively works. I guess it should be possible to used it in the binding as well, right? I will give feedback as soon as i have tested.
Greetings Kai

Ok - I will check with my Nanoleaf and disconnect the Rhythm module from it. I have to admit that I didn’t tested this case so far :thinking:, but it seems that this might be the reason for the NullPointer…

No - I probably have more than 10 token generated over time without any issues.

Hi Kai, Markus,

I tested with my Nanoleaf and disconnected the Rhythm module from it. In this case, the controller returns false for the rhythmState channel, but for all other rhythm-channels null. This leads to the null pointer exception you’ve seen.

I’ve fixed the issue in my repo and uploaded a new JAR. Curious to see if this fixes your issues.

Martin

It stay’s online. Perfect. Thank’s Martin.
I will test the rest.
Greetings and thanks again,
Markus

A little improvement to the docs, now that the binding is in master:

Hi Martin,
the updated JAR solved my problem as well. I defined the Nanoleaf thing in a things file and did the pairing by pressing the on-off button for about 5 seconds till it started blinking. The defined thing immediately went online and stayed online. I was able to lookup the authToken in the openhab rest page and add it to the nanoleaf thing definition - and the thing remained online. This issue is fixed, further tests with items will follow the next days. Many thanks!
Greetings Kai

Did someone try this with the Nanoleaf Canvas? I installed the binding, get my token… put it in the controller. As long as pairing is on its green… then disconnects. I can also find the single modules. But als is offline. Get runtime error…

[WARN ] [al.handler.NanoleafControllerHandler] - Update job failed
java.lang.NullPointerException: null
at org.openhab.binding.nanoleaf.internal.handler.NanoleafControllerHandler.updateFromControllerInfo(NanoleafControllerHandler.java:472) ~[?:?]
at org.openhab.binding.nanoleaf.internal.handler.NanoleafControllerHandler.runUpdate(NanoleafControllerHandler.java:338) ~[?:?]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:?]
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [?:?]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [?:?]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [?:?]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:?]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:?]
at java.lang.Thread.run(Thread.java:748) [?:?]
2019-03-06 09:21:59.981 [WARN ] [al.handler.NanoleafControllerHandler] - Update job failed

No, I did not tested with the Nanoleaf Canvas.

But from the runtime error it looks like you get stuck at the same point where the binding is discovering the Rhythm module settings. I’ve fixed this issue when the Rhythm is not attached in a new version of the binding, for which you can download the JAR file from here.

Would be great if you could test again with this new version to see if the Canvas device works as well with the binding.

Thanks and regards
Martin

This was the version I already downloaded an testet with…

Can you try to send us a sample response from your Canvas controller info endpoint? This should be a GET request to http://<your canvas ip>:<port, e.g. 16021>/api/v1/<auth_token>/ (the <auth_token> can be obtained by pressing the button on the controller for 5 seconds - I assume this is similar to the light panels? - and then sending a POST request to http://<your canvas ip>:<port, e.g. 16021>/api/v1/new)

I suspect that the response from a Canvas device may not include any Rhythm module information at all. Looking at http://forum.nanoleaf.me/docs/openapi#_e0963whljqgi, this seems to be the case…

Is there actually a Rhythm module available for the Canvas device?

Thanks and regards
Martin

Ill do that tomorrow , i think the rythm Module is already build in the conrtol module. As it reacts to music.

this is the result:
{“name”:“Canvas 9896”,“serialNo”:“S18494C4346”,“manufacturer”:“Nanoleaf”,“firmwareVersion”:“1.1.0”,“model”:“NL29”,“discovery”:{},“effects”:{“effectsList”:[“Black and White”,“Color Burst”,“Energize”,“Falling Whites”,“Fireworks”,“Flames”,“Forest”,“Inner Peace”,“Lavender Fields”,“Magic Strobe”,“Memory”,“Meteor Shower”,“Nature Zen”,“Nemo”,“Netflix And Chill”,“Northern Lights”,“Ocean”,“Paint Splatter”,“Pulse Pop Beats”,“Purple Rain”,“Rain”,“Rhythmic Northern Lights”,“Romantic”,“Scary Night In The Forest”,“Sound Bar”,“Starry Night”,“Stranger Things”,“Streaking Notes”,“Tron Legacy”,“Vintage Modern”,“Whack A Mole”,“moonlight”],“select”:“Shuffle”},“panelLayout”:{“globalOrientation”:{“value”:0,“max”:360,“min”:0},“layout”:{“numPanels”:17,“sideLength”:100,“positionData”:[{“panelId”:3566,“x”:500,“y”:200,“o”:0,“shapeType”:2},{“panelId”:34658,“x”:400,“y”:200,“o”:0,“shapeType”:2},{“panelId”:28371,“x”:300,“y”:200,“o”:270,“shapeType”:2},{“panelId”:52829,“x”:200,“y”:200,“o”:0,“shapeType”:2},{“panelId”:56525,“x”:100,“y”:200,“o”:270,“shapeType”:2},{“panelId”:24505,“x”:100,“y”:100,“o”:180,“shapeType”:2},{“panelId”:9777,“x”:100,“y”:0,“o”:180,“shapeType”:2},{“panelId”:56263,“x”:0,“y”:200,“o”:0,“shapeType”:2},{“panelId”:9148,“x”:0,“y”:100,“o”:0,“shapeType”:2},{“panelId”:30647,“x”:0,“y”:300,“o”:90,“shapeType”:2},{“panelId”:61965,“x”:0,“y”:400,“o”:0,“shapeType”:2},{“panelId”:7154,“x”:0,“y”:500,“o”:90,“shapeType”:2},{“panelId”:31883,“x”:0,“y”:600,“o”:90,“shapeType”:2},{“panelId”:45833,“x”:100,“y”:400,“o”:0,“shapeType”:2},{“panelId”:34158,“x”:100,“y”:300,“o”:90,“shapeType”:2},{“panelId”:45707,“x”:200,“y”:300,“o”:90,“shapeType”:2},{“panelId”:46774,“x”:300,“y”:300,“o”:90,“shapeType”:2}]}},“state”:{“brightness”:{“value”:100,“max”:100,“min”:0},“colorMode”:“effect”,“ct”:{“value”:4000,“max”:6500,“min”:1200},“hue”:{“value”:0,“max”:360,“min”:0},“on”:{“value”:false},“sat”:{“value”:0,“max”:100,“min”:0}}}

Thanks! So there is no rhythm element at all in the response from a Canvas device, which is different from the Light Panels.

I’ve updated the code + JAR to check for this condition.

@terriblefox: Can you give it another try with the updated JAR?

Version in Karaf is now 2.5.0.201903071144

Thanks
Martin

Now it works perfect…

I can turn it on and off
can change color sat and brightness
I can change scenes

I can’t control the separate canvas titles