Package: nanoleafapi
nanoleafapinanoleafapiis a Python 3 wrapper for the Nanoleaf OpenAPI. It provides an easy way to use many of the functions available in the API. It supports the Light Panels (previously Aurora), Canvas and Shapes (Hexagons, Triangles and Elements). It doesnotsupport the Nanoleaf Essentials range.Nanoleaf API:https://forum.nanoleaf.me/docs/openapiDetailed package documentation:https://nanoleafapi.readthedocs.ioIMPORTANT: As of version 2.0.0, there have been some API changes relating to how the authentication token is generated and stored, please re-read theUsagesection.Table of ContentsInstallationPrerequisitesUsageMethodsEffectsEventsDigital TwinsErrorsInstallationTo install the latest stable release:python -m pip install nanoleafapiPrerequisitesYou must know the IP address of the Nanoleaf device. This can be either be done using your own methods or by using the disovery module. This module uses SSDP and should workbutI have found cases of this method not functioning properly. If it doesn't work, and gives an empty dictionary please identify the IP of the Nanoleaf device yourself.To use the discovery module:fromnanoleafapiimportdiscoverynanoleaf_dict=discovery.discover_devices()This will return a dictionary in the format:{name: ip}.UsageThere is just one class that contains all relevant functions for controlling the lights. To get started:fromnanoleafapiimportNanoleafNext, a Nanoleaf object can be created with the following line of code.IF you don't have an authentication token yet, hold the power button for 5-7 seconds on your Nanoleaf device before running the following code. This will generate a new token and save it to your user directory to use for future uses of this package.nl=Nanoleaf("ip")You can now use the commands to control the panels as displayed in the example below.nl.toggle_power()# Toggle powernl.set_color((255,0,0))# Set colour to redMethodsAll of the following methods can be called with the Nanoleaf object you created.For more information about the Nanoleaf API:https://forum.nanoleaf.me/docs/openapiFor more in-depth documentation about this package visit:https://nanoleafapi.readthedocs.ioUser Managementcreate_auth_token()# Creates an authentication token and stores it in the user's home directory.delete_auth_token()# Deletes an authentication token from the device and the token storage file.Generalget_info()# Returns device information dictionaryget_name()# Returns the current device namecheck_connection()# Raises NanoleafConnectionError if connection failsPowerget_power()# Returns True if lights are on, otherwise Falsepower_off()# Powers off the lightspower_on()# Powers on the lightstoggle_power()# Toggles light on/offColourColours are generated using HSV (or HSB) in the API, and these individual values can be adjusted using methods which are as described,hue,saturation,brightness/value. The method in this section uses RGB (0-255) and converts this to HSV.There are already some pre-set colours which can be imported to be used with theset_color()method:fromnanoleafapiimportRED,ORANGE,YELLOW,GREEN,LIGHT_BLUE,BLUE,PINK,PURPLE,WHITETheset_color()method can then be called, passing in either a pre-set colour or your own RGB colour in the form of a tuple:(r, g, b).set_color((r,g,b))# Set all lights to RGB colour. Pass the colour as a tuple.set_color(RED)# Same result but using a pre-set colour.Brightnessset_brightness(brightness,duration)# Sets the brightness of the lights (accepts values between 0-100)increment_brightness(value)# Increments the brightness by set amount (can also be negative)get_brightness()# Returns current brightnessHueUse these if you want to change the HSV values manually, otherwise useset_color()for colour change using RGB.set_hue(value)# Sets the hue of the lights (accepts values between 0-360)increment_hue(value)# Increments the hue by set amount (can also be negative)get_hue()# Returns current hueSaturationUse these if you want to change the HSV values manually, otherwise useset_color()for colour change using RGB.set_saturation(value)# Sets the saturation of the lights (accepts value between 0-100)increment_saturation(value)# Increments the saturation by set amount (can also be negative)get_saturation()# Returns current saturationIdentifyThis is usually used to identify the current lights by flashing them on and off.identify()Colour Temperatureset_color_temp(value)# Sets the colour temperature of the lights (accepts between 1200-6500)increment_color_temp(value)# Increments the colour temperature by set amount (can also be negative)get_color_temp()# Returns current colour temperatureColour Modeget_color_mode()# Returns current colour modeEffectsget_current_effect()# Returns either name of current effect if available or *Solid*/*Static*/*Dynamic*.list_effects()# Returns a list of names of all available effects.effect_exists(name)# Helper method which determines whether the given string exists as an effect.set_effect(name)# Sets the current effect.Custom Effectspulsate((r,g,b),speed)# Displays a pulsate effect with the specified colour and speed.flow([(r,g,b),(r,g,b),...],speed)# Displays a sequence of specified colours and speed.spectrum(speed)# Displays a spectrum cycling effect with the specified speed.Write Effectwrite_effect(effect_dict)# Sets a user-created effect.Writing effects is rather complicated; you need to follow the the exact format for the effect dictionary, which can be found here:https://forum.nanoleaf.me/docs/openapi#_u2t4jzmkp8ntIn future updates, I hope to add a way to make this process easier, but for now an example of a valid effect dictionary is provided below:effect_data={"command":"display","animName":"New animation","animType":"random","colorType":"HSB","animData":None,"palette":[{"hue":0,"saturation":100,"brightness":100},{"hue":120,"saturation":100,"brightness":100},{"hue":180,"saturation":100,"brightness":100}],"brightnessRange":{"minValue":50,"maxValue":100},"transTime":{"minValue":50,"maxValue":100},"delayTime":{"minValue":50,"maxValue":100},"loop":True}Inputting an invalid dictionary will raise a NanoleafEffectCreationError.Enable UDP Streamingnl.enable_extcontrol()# Enables UDP extControl APIThis enables the UDP extControl API, which is detailed further in thedocumentation. There is also an example provided by@erhan-in their PR for adding this feature, which gives a great first example. This can be foundhere.EventsCreates an event listener for the different types of events.register_event(function,event_types)You should pass your own function with one argument (event as a dictionary). This function will run every time a new event is received.IMPORTANT: You cannot currently callregister_event()more thanoncedue to API limitations. Instead, distinguish between the events in your function using the dictionary data.A list of event types you would like to listen for should also be passed. You can register up to 4 events (all of them), and these are listed below:Event IDs:State (changes in power/brightness): 1
Layout: 2
Effects: 3
Touch (Canvas/Shapes only): 4Example Usagedefevent_function(event):print(event)# Register for all eventsnl.register_event(event_function,[1,2,3,4])Example OutputWhen an event occurs, theevent_function()will run and therefore in this case, print the event dictionary.{"events":[{"attr":2,"value":65}]}# Example of state event (1){"events":[{"attr":1,"value":"Falling Whites"}]}# Example of effects event (3){"events":[{"panelId":7397,"gesture":0}]}# Example of touch event (4)NanoleafDigitalTwinThis class is used to make a digital twin (or copy) of the Nanoleaf device, allowing you to change the colour of individual tiles and then sync all the changes
at once to the real device.To create an instance of this class, you must initialise it with a Nanoleaf object:fromnanoleafapiimportNanoleaf,NanoleafDigitalTwinnl=Nanoleaf("192.168.0.2")digital_twin=NanoleafDigitalTwin(nl)Utilitynl.get_ids()# Returns a list of panel IDsColourSetting the colour is all managed by using an RGB tuple, in the format:(R, G, B).digital_twin.set_color(panel_id,(255,255,255))# Sets the panel with specified ID to whitedigital_twin.set_all_colors((255,255,255))# Sets all panels to whitedigital_twin.get_color(panel_id)# Gets the colour of a specified paneldigital_twin.get_all_colors()# Returns a dictionary of {panel_id: (R, G, B)}SyncThe sync method applies the changes to the real Nanoleaf device, based on the changes made here.digital_twin.sync()# Syncs with the real Nanoleaf counterpartFull NanoleafDigitalTwin examplefromnanoleafapiimportNanoleaf,NanoleafDigitalTwinimportrandomnl=Nanoleaf("ip")digital_twin=NanoleafDigitalTwin(nl)# get a list of all panelspanels=nl.get_ids()forpanel_idinpanels:# set each panel to a random RGB valuedigital_twin.set_color(panel_id,(random.randint(0,255),random.randint(0,255),random.randint(0,255),))# call 'sync' to copy the "twin" state to the actual panelsdigital_twin.sync()ErrorsNanoleafRegistrationError()# Raised when token generation mode not active on deviceNanoleafConnectionError()# Raised when there is a connection error during check_connection() methodNanoleafEffectCreationError()# Raised when there is an error with an effect dictionary/method arguments