[nanoleaf] Nanoleaf Aurora binding (just started development, collecting requirements)

I am interested in this binding as I intend to integrate nanoleaf canvas in my new home.
One very nice feature (if feasible) would be to trigger other actions when touching one of the canvas panels, as they are touch sensitive.
It would be great to use them as „buttons“ maybe even dependent on the color they actually show acting as different virtual switches.

So lets say in the entrance area of my home some of the panels are used to e.g.

a) activate alarm system (changing color when alarm system activates or blinking during armament)
b) emergency button (if you are threatened at the door) when touched, triggering a pre-alert warning
c) checkout of inhabitants (each kid has its own panel to press when leaving home/coming home)

That would allow so many things if the API provides such kind of functionality.

What do you think?

BR

Uwe

You’ve got some great ideas there…

Almost enough to get me to buy some canvas panels…

But not quite enough to convince me to get the kids to go with them…

Training the kids will be the hard part (however if there is benefit for them when they check out/check in they might be supportive :wink:

I signed in to the dev forum of nanoleaf and found out that the API indeed supports to receive event notifications (per panel) for one tap or double tap. So in principle my idea should work with openHAB even without a binding but having this all available in a binding would be superb and the price of the panels now becoming also switches seems then ok to me.

Also for disabled or elder people I guess that illuminared/colored panels providing visible information/feedback and easy touch actions would be helpful.

1 Like

That is actually a great idea. I have to keep that in mind for my grandmother.

I can’t thank you enough! It works flawlessly! I love it!
Improvemts:

  • strange behaviour when setting a colour with Colorpicker in sitemap
  • just installed it. maybe I’ll add things later but currently I am happy af!

Thanks!

Thank you Felix for your feedback! Please note that the most current version of the binding can be found here. Curious to see if you still see the strange behaviour with the Colorpicker with this version.

I have also a development version which fixes a bug when there is no Rhythm module connected to the Nanoleaf Light Panels, and adds experimental support for the Nanoleaf Canvas device.

Still waiting for @terriblefox (Binding Request: Nanoleaf Aurora (LED Design Triangle) to test it with his device ;-), to prepare a new pull request.

1 Like

Hey there=)

I just spent some more time with the binding and I love it!

This doesn’t happen anymore. I think it was just glitched once. works perfectly on pc and mobile.

It works flawlessly on my Nanoleaf Aurora, I can’t think of any improvements^^
Great work there!:heart_eyes:

Thank you for developing this!

I just installed the 2.5.0-SNAPSHOT jar and basic control works right out of the box. The addon site mentions that I can also add the single panels as things via auto discovery once the auth token was entered. I’d love to do that, since I want to use a few selected panels for notifications :slight_smile:

However when I hit discovery, no panels are found. I could probably enter them manually, but how do I get the ids?

I’m on openhab 2.4 stable

PS: I’m also confused … why is the power button a drop down box in paper ui->control? Usually they are those little left-right flip switches. The thing looks the same as my other power switches.

This would be so cool😍

I can control it with homebridge just fine. But I’d love to have it in openhab for the more advanced stuff. Think a weather forecast in the morning with the next days or ours color coded on the panels :slight_smile:

Hi Daniel,

with a successfully paired controller, the individual panels should be correctly discovered by starting another scan for the Nanoleaf binding.

If this does not work for you, can you check your openhab log file for any error messages? You may also want to set the log level to INFO with

log:set DEBUG org.openhab.binding.nanoleaf

to see more details.

Thanks and regards
Martin

I checked the logfile yesterday, but there was nothing. Now, with loglevel debug it has only this:

2019-04-23 22:20:49.061 [DEBUG] [ery.NanoleafMDNSDiscoveryParticipant] - Nanoleaf Type: NL22
2019-04-23 22:20:49.065 [DEBUG] [ery.NanoleafMDNSDiscoveryParticipant] - Nanoleaf found: 192.168.0.40 16021
2019-04-23 22:20:49.068 [DEBUG] [ery.NanoleafMDNSDiscoveryParticipant] - Adding Nanoleaf lightpanels to inbox: 62D0E39E8239 at 192.168.0.40
2019-04-23 22:20:49.070 [DEBUG] [ery.NanoleafMDNSDiscoveryParticipant] - Nanoleaf Type: NL22

There is an older error in the logfile, but it’s from the time when I was still playing around with the items/control.

2019-04-22 21:21:24.165 [ERROR] [nal.common.AbstractInvocationHandler] - An error occurred while calling method 'ThingHa                                                ndler.handleCommand()' on 'org.openhab.binding.nanoleaf.internal.handler.NanoleafHandler@1b836fd': Unhandled command typ                                                e
org.openhab.binding.nanoleaf.internal.NanoleafException: Unhandled command type
        at org.openhab.binding.nanoleaf.internal.handler.NanoleafHandler.sendEffectCommand(NanoleafHandler.java:148) ~[?                                                :?]
        at org.openhab.binding.nanoleaf.internal.handler.NanoleafHandler.handleCommand(NanoleafHandler.java:189) ~[?:?]
        at sun.reflect.GeneratedMethodAccessor39.invoke(Unknown Source) ~[?:?]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[?:?]
        at org.eclipse.smarthome.core.internal.common.AbstractInvocationHandler.invokeDirect(AbstractInvocationHandler.j                                                ava:153) [102:org.eclipse.smarthome.core:0.10.0.oh240]
        at org.eclipse.smarthome.core.internal.common.InvocationHandlerSync.invoke(InvocationHandlerSync.java:59) [102:o                                                rg.eclipse.smarthome.core:0.10.0.oh240]
        at com.sun.proxy.$Proxy138.handleCommand(Unknown Source) [212:org.openhab.binding.nanoleaf:2.5.0.201901190212]
        at org.eclipse.smarthome.core.thing.internal.profiles.ProfileCallbackImpl.handleCommand(ProfileCallbackImpl.java                                                :75) [109:org.eclipse.smarthome.core.thing:0.10.0.oh240]
        at org.eclipse.smarthome.core.thing.internal.profiles.SystemDefaultProfile.onCommandFromItem(SystemDefaultProfil                                                e.java:49) [109:org.eclipse.smarthome.core.thing:0.10.0.oh240]
        at sun.reflect.GeneratedMethodAccessor38.invoke(Unknown Source) ~[?:?]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
        at java.lang.reflect.Method.invoke(Method.java:498) ~[?:?]
        at org.eclipse.smarthome.core.internal.common.AbstractInvocationHandler.invokeDirect(AbstractInvocationHandler.j                                                ava:153) [102:org.eclipse.smarthome.core:0.10.0.oh240]
        at org.eclipse.smarthome.core.internal.common.Invocation.call(Invocation.java:53) [102:org.eclipse.smarthome.cor                                                e:0.10.0.oh240]
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:?]
        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) [?:?]

But I doubt that it has an effect here?

Just to be sure, I restarted the openhab service. After it was back online, I tested whether the binding works and then tried the scan again, three times. The first time nothing happened (maybe openhab still starting up?) the two other times are in the log.

2019-04-23 22:26:51.901 [DEBUG] [eaf.internal.handler.NanoleafHandler] - Received channel: nanoleaf:lightpanels:62D0E39E8239:power, command: OFF
2019-04-23 22:26:52.136 [DEBUG] [eaf.internal.handler.NanoleafHandler] - API response code: 204
2019-04-23 22:26:54.745 [DEBUG] [eaf.internal.handler.NanoleafHandler] - Received channel: nanoleaf:lightpanels:62D0E39E8239:power, command: ON
2019-04-23 22:26:55.004 [DEBUG] [eaf.internal.handler.NanoleafHandler] - API response code: 204
2019-04-23 22:27:15.001 [DEBUG] [eaf.internal.handler.NanoleafHandler] - Update channels for light panels nanoleaf:lightpanels:62D0E39E8239
2019-04-23 22:27:15.024 [DEBUG] [eaf.internal.handler.NanoleafHandler] - API response code: 200
2019-04-23 22:27:38.713 [DEBUG] [ery.NanoleafMDNSDiscoveryParticipant] - Nanoleaf Type: NL22
2019-04-23 22:27:38.719 [DEBUG] [ery.NanoleafMDNSDiscoveryParticipant] - Nanoleaf found: 192.168.0.40 16021
2019-04-23 22:27:38.722 [DEBUG] [ery.NanoleafMDNSDiscoveryParticipant] - Adding Nanoleaf light panels to inbox: 62D0E39E8239 at 192.168.0.40
2019-04-23 22:27:38.726 [DEBUG] [ery.NanoleafMDNSDiscoveryParticipant] - Nanoleaf Type: NL22
2019-04-23 22:27:53.920 [DEBUG] [ery.NanoleafMDNSDiscoveryParticipant] - Nanoleaf Type: NL22
2019-04-23 22:27:53.925 [DEBUG] [ery.NanoleafMDNSDiscoveryParticipant] - Nanoleaf found: 192.168.0.40 16021
2019-04-23 22:27:53.929 [DEBUG] [ery.NanoleafMDNSDiscoveryParticipant] - Adding Nanoleaf light panels to inbox: 62D0E39E8239 at 192.168.0.40
2019-04-23 22:27:53.932 [DEBUG] [ery.NanoleafMDNSDiscoveryParticipant] - Nanoleaf Type: NL22
2019-04-23 22:28:15.051 [DEBUG] [eaf.internal.handler.NanoleafHandler] - Update channels for light panels nanoleaf:lightpanels:62D0E39E8239
2019-04-23 22:28:15.071 [DEBUG] [eaf.internal.handler.NanoleafHandler] - API response code: 200

Can I manually look for the IDs? I found another thread with an URL where you supposedly see them, but that just returns a blank page in my browser (yes, I changed the ip from the example).

To add the panels manually, you could follow these steps:

  • Get the controller auth token by calling the openhab REST API with http(s)://<your_openhab-ip:port>/rest/things
  • Search in the response for the string authToken which will give you the Nanoleaf controller thing auth token
  • In a browser/REST client, call http://<your-nanoleaf-ip:port>/api/v1/<auth_token>/
  • You will get back a JSON-formatted response which contains an array of all your panels, something like

... "panelLayout":{"layout":{"numPanels":14,"sideLength":150,"positionData":[{"panelId":135,"x":0,"y":173,"o":300,"shapeType":0}, ...

  • panelId (135 in the example above) refers to the id you have to specify as the id attribute of the lightpanel thing(s) in your Thing file

I will also check the pairing of panels again with my device to see if I run into the same issues…

Best regards
Martin

Hey there =)

I am confused on where to put the ID in. Is it possible to do it in the Paper UI?

Is this an old version of the Binding I have? It says its 2.5.0. Or do I have to do it via a file in the Editor?
If so can you please share a screenshot on what to add? Especially for the Individual Light Panels.

Thanks!

You can check out the binding documentation which has an example of a thing file which contains the controller/bridge definition with two (light)panels. The id is set as a configuration parameter [ id=... ] on each lightpanel thing type.

Thanks for the advice. Works perfectly!

One last thing: there is a spelling mistake in the binding documentation: it says nanolead-rules

Is this binding usable with OH 2.3.0 or do i need a later version?

So just tried to add the jar to my 2.3.0 and see if i can make it work. It appears i cant …

At first i added it via Paper UI, which lead to a controller that was usable (tested with power channel). I could not discover any panels however. The solution this thread provides is to add all things as text files.
I cant add the controller as things file properly though, the port and ip adress are always missing in paper ui (when i look at it). The thing is shown as offline.
I see the following error: “2019-07-12 23:19:11.825 [ERROR] [eaf.internal.handler.NanoleafHandler] - URI could not be parsed with path /api/v1/” The token is correct.

Sidenote: if i use the string “nanoleaf:controller:MyLightPanels” from the documentation i get alot exceptions in my logs, and if i use “nanoleaf:lightpanels:MyLightPanels” i only get the above error regarding the API call.

Is this because im on 2.3.0? Or is there any point i am missing?

Hi Martin

I have a question regarding the Nanoleaf binding - good job by the way - it’s this:
I downloaded the binding and copied the .jar file to /usr/share/openhab2/addons which caused it to pop up in the Paper UI inbox from where I was able to activate it, it automagically detected the Canvas I had on-line and after pairing the panels activated the control in Paper UI - this is where I became confused - I could switch the panels on and off, control brightness and colour from Control but could not activate any additional functions.
I created the .map in transform, the sitemap, items and the thing and I could control all of the functions - the question is why? Does it require both the thing I created and the thing which automagically appeared or is there a way I can massage them into a single thing?

I have not defined anything in .things. (auto-discover only)

My .items looks like:

Switch CanvasKitchenPower       (kitchen) { channel = "nanoleaf:controller:9F276836E179:power" }
Color CanvasKitchenColor                  { channel = "nanoleaf:controller:9F276836E179:color" }
Dimmer CanvasKitchenTempSlider            { channel = "nanoleaf:controller:9F276836E179:colorTemperature" }
Number CanvasKitchenTempAbs               { channel = "nanoleaf:controller:9F276836E179:colorTemperatureAbs" }
String CanvasKitchenColorMode             { channel = "nanoleaf:controller:9F276836E179:colorMode" }
String CanvasKitchenEffect                { channel = "nanoleaf:controller:9F276836E179:effect" }
Switch CanvasKitchenRhythmState           { channel = "nanoleaf:controller:9F276836E179:rhythmState" }
Switch CanvasKitchenRhythmActive          { channel = "nanoleaf:controller:9F276836E179:rhythmActive" }
Number CanvasKitchenRhythmMode            { channel = "nanoleaf:controller:9F276836E179:rhythmMode" }

Number CanvasTouchId      (canvasTouch)
Number CanvasTouchGesture (canvasTouch) 

Example rule:

rule "Nanoleaf touch"
when
    Member of canvasTouch received update
then
    logInfo("CanvasTouch", triggeringItem.name + " State=" + triggeringItem.state)

    switch(triggeringItem.name) {
        case "CanvasTouchId":{  
          logInfo("CanvasTouch", "PanelId=" + triggeringItem.state + " gesture=" + CanvasTouchGesture.state)
          switch(triggeringItem.state) {
              case 22092: {
                  CanvasKitchenPower.sendCommand(if (CanvasKitchenPower.state==ON) OFF else ON)
                  if (CanvasKitchenPower.state==OFF) {
                      CanvasKitchenColor.sendCommand(100)
                      CanvasKitchenEffect.sendCommand("Fray")
                  }
              }
              case 15141: {
                  CanvasKitchenColor.sendCommand(25)
                  CanvasKitchenEffect.sendCommand("WhiteDimmed")
              }
              case 42426: {
                  BuildInKjokkenBench.sendCommand(if (BuildInKjokkenBench.state==ON) OFF else ON)
              }
              case 42633: {
                  if (CanvasKitchenEffect.state != "Meteor Shower") {
                    CanvasKitchenEffect.sendCommand("Meteor Shower")
                    BuildInKjokkenBench.sendCommand(OFF)
                  } else {
                    CanvasKitchenColor.sendCommand(25)
                    CanvasKitchenEffect.sendCommand("WhiteDimmed")
                  }
              }
              case 38949: {
                  var HSBType currentState
                  currentState = CanvasKitchenColor.state as HSBType
                  var DecimalType new_H = currentState.hue
                  var PercentType new_S = currentState.saturation
                  var PercentType new_B = new PercentType(currentState.brightness as Number + 10)
                  logInfo("File", "color test: hue = {} sat = {} bright = {}", new_H, new_S, new_B)
                  var HSBType newState = new HSBType(new_H, new_S, new_B)
                  logInfo("File", "color test: hue = {} sat = {} bright = {}", new_H, new_S, new_B)
                  CanvasKitchenColor.sendCommand(newState)
                  logInfo("CanvasTouch", "CanvasKitchenColor=" + CanvasKitchenColor.state)
              }
              case 20017: {
                  var HSBType currentState
                  currentState = CanvasKitchenColor.state as HSBType
                  var DecimalType new_H = currentState.hue
                  var PercentType new_S = currentState.saturation
                  var PercentType new_B = new PercentType(currentState.brightness as Number - 10)
                  logInfo("File", "color test: hue = {} sat = {} bright = {}", new_H, new_S, new_B)
                  var HSBType newState = new HSBType(new_H, new_S, new_B)
                  logInfo("File", "color test: hue = {} sat = {} bright = {}", new_H, new_S, new_B)
                  CanvasKitchenColor.sendCommand(newState)
                  logInfo("CanvasTouch", "CanvasKitchenColor=" + CanvasKitchenColor.state)
              }
          }
        } 
        default: {
        }
    }
end

rule "Nanoleaf color"
when
    Item CanvasKitchenColor changed
then
    logInfo("CanvasTouch", CanvasKitchenColor.name + " State=" + CanvasKitchenColor.state)
end

rule "Nanoleaf effect"
when
    Item CanvasKitchenEffect changed
then
    logInfo("CanvasTouch", CanvasKitchenEffect.name + " State=" + CanvasKitchenEffect.state)
end