Skip to main content

A Python 3 wrapper for the Nanoleaf OpenAPI, for use when controlling the Light Panels, Canvas and Shapes (including Hexagons)

Project description

nanoleafapi

PyPI version Documentation Status Downloads

nanoleafapi is 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 does not support the Nanoleaf Essentials range.

Nanoleaf API: https://forum.nanoleaf.me/docs/openapi

Detailed package documentation: https://nanoleafapi.readthedocs.io

IMPORTANT: 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 the Usage section.

Table of Contents

  1. Installation
  2. Prerequisites
  3. Usage
  4. Digital Twins
  5. Errors

Installation

To install the latest stable release:

python -m pip install nanoleafapi

Prerequisites

You 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 work but I 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:

from nanoleafapi import discovery

nanoleaf_dict = discovery.discover_devices()

This will return a dictionary in the format: {name: ip}.

Usage

There is just one class that contains all relevant functions for controlling the lights. To get started:

from nanoleafapi import Nanoleaf

Next, 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 power
nl.set_color((255, 0, 0))     # Set colour to red

Example setup

Methods

All 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/openapi

For more in-depth documentation about this package visit: https://nanoleafapi.readthedocs.io

User Management

create_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.

General

get_info()         # Returns device information dictionary
get_name()         # Returns the current device name
check_connection() # Raises NanoleafConnectionError if connection fails

Power

get_power()               # Returns True if lights are on, otherwise False
power_off()               # Powers off the lights
power_on()                # Powers on the lights
toggle_power()            # Toggles light on/off

Colour

Colours 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 the set_color() method:

from nanoleafapi import RED, ORANGE, YELLOW, GREEN, LIGHT_BLUE, BLUE, PINK, PURPLE, WHITE

The set_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.

Brightness

set_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 brightness

Hue

Use these if you want to change the HSV values manually, otherwise use set_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 hue

Saturation

Use these if you want to change the HSV values manually, otherwise use set_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 saturation

Identify

This is usually used to identify the current lights by flashing them on and off.

identify()

Colour Temperature

set_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 temperature

Colour Mode

get_color_mode()      # Returns current colour mode

Effects

get_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 Effects

pulsate((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 Effect

write_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#_u2t4jzmkp8nt

In 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 Streaming

nl.enable_extcontrol()    # Enables UDP extControl API

This enables the UDP extControl API, which is detailed further in the documentation. There is also an example provided by @erhan- in their PR for adding this feature, which gives a great first example. This can be found here.

Events

Creates 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 call register_event() more than once due 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): 4

Example Usage

def event_function(event):
    print(event)

# Register for all events
nl.register_event(event_function, [1, 2, 3, 4])

Example Output

When an event occurs, the event_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)

NanoleafDigitalTwin

This 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:

    from nanoleafapi import Nanoleaf, NanoleafDigitalTwin

    nl = Nanoleaf("192.168.0.2")
    digital_twin = NanoleafDigitalTwin(nl)

Utility

    nl.get_ids()       # Returns a list of panel IDs

Colour

Setting 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 white
    digital_twin.set_all_colors((255, 255, 255))        # Sets all panels to white
    digital_twin.get_color(panel_id)                    # Gets the colour of a specified panel
    digital_twin.get_all_colors()                       # Returns a dictionary of {panel_id: (R, G, B)}

Sync

The sync method applies the changes to the real Nanoleaf device, based on the changes made here.

    digital_twin.sync()    # Syncs with the real Nanoleaf counterpart

Full NanoleafDigitalTwin example

from nanoleafapi import Nanoleaf, NanoleafDigitalTwin
import random

nl = Nanoleaf("ip")
digital_twin = NanoleafDigitalTwin(nl)

# get a list of all panels
panels = nl.get_ids()

for panel_id in panels:
    # set each panel to a random RGB value
    digital_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 panels
digital_twin.sync()

Errors

NanoleafRegistrationError()   # Raised when token generation mode not active on device
NanoleafConnectionError()     # Raised when there is a connection error during check_connection() method
NanoleafEffectCreationError() # Raised when there is an error with an effect dictionary/method arguments

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nanoleafapi-2.1.2.tar.gz (19.0 kB view details)

Uploaded Source

Built Distribution

nanoleafapi-2.1.2-py3-none-any.whl (16.4 kB view details)

Uploaded Python 3

File details

Details for the file nanoleafapi-2.1.2.tar.gz.

File metadata

  • Download URL: nanoleafapi-2.1.2.tar.gz
  • Upload date:
  • Size: 19.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.8.13

File hashes

Hashes for nanoleafapi-2.1.2.tar.gz
Algorithm Hash digest
SHA256 cb8c5407197b4ab8bd79e5ee791020667579f0fbbe92009e9014587d74ea2a97
MD5 f794312cb38e10b98a3ad088e72e301e
BLAKE2b-256 4b5d595ac5bd1c3c6e604aace9c1346dfbfdb2b38ab5b3c4e5ddc0d51a70e770

See more details on using hashes here.

File details

Details for the file nanoleafapi-2.1.2-py3-none-any.whl.

File metadata

  • Download URL: nanoleafapi-2.1.2-py3-none-any.whl
  • Upload date:
  • Size: 16.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.1 CPython/3.8.13

File hashes

Hashes for nanoleafapi-2.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 cd87c85c8d6f1c0384c3d87ec6bd66a7110289f50257f006df5876b44b0947a5
MD5 1971ba6c7e36c797f93de900a94e1ab6
BLAKE2b-256 7cd0cb4e77db0692a3555840e1f619fde6ca8941c7e8d11d870783765c886210

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page