View Source Delux (delux v0.4.0)
Use LEDs for your user interface
delux
simplifies creating and running LED blink patterns for use as part of a
user interface for an embedded hardware. This library provides:
- Low overhead LED control via Linux's Sysclass interface - blink sequences get compiled down so that they can be run inside the Linux kernel.
- Built-in LED effects for common use cases like blinking, cycling LED colors, etc.
- Prioritization of LED effects
- Support for many physical LED configurations
- Nice textual descriptions of what the LED is doing to support remote debug
This library is primarily intended for devices with 1 to 10 LEDs. It's currently not for Neopixels and other "smart" LEDs that are more typically found in larger numbers, but could be used for a similar purpose.
Before diving in, some terminology is needed:
- LED - one light emitting element. This doesn't have to be an LED, but the
Linux kernel must think that it is and show a directory for it under
/sys/class/leds/
. - Indicator - a group of 1, 2, or 3 LEDs that a user would perceive as one. This could be a lone green LED, or a red, green and blue LED in one package, or any combination.
- Program - a one-time or repeating set of instructions for controlling an indicator.
- Pattern - a low-level sequence of brightness and duration tuples for controlling one LED
- Slot - a holder for a program. Slots are ordered so a program put in a higher priority slot will take precedence over one in a lower priority slot. For example, if there's a UI feedback slot and a network status slot, programs running in the UI feedback slot could take precedence.
To give a flavor of how delux
works, here's an example that configures
delux
with one green LED and then blinks it at 2 Hz:
iex> Delux.start_link(indicators: %{default: %{green: "led0"}})
iex> Delux.render(Delux.Effects.blink(:green, 2))
iex> Delux.info()
green at 2 Hz
This starts Delux with one indicator, :default
, that has a green LED known to
Linux as "led0"
. The Delux.Effects.blink/2
function creates a 2 Hz blinking
program for Delux to render. With nothing else specified, Delux.render/1
runs
the program on the default indicator in the default slot.
Link to this section Summary
Types
Configuration for an indicator
The name for one indicator
Delux configuration options
A name of a slot for an indicator program
Functions
Adjust the overall brightness of all indicators
Returns a specification to start this module under a supervisor.
Clear out all programs in the specified slot
Call info/2
with the specified indicator
Print out info about an indicator
Call info_as_ansidata/2
with the defaults
Call info_as_ansidata/2
with the specified indicator
Return user-readable information about an indicator
Helper for rendering a program when using Delux's defaults
Helper for rendering a program to a slot
Update one or more indicators to a new program
Start an Delux GenServer
Link to this section Types
@type indicator_config() :: %{ optional(:red) => String.t(), optional(:green) => String.t(), optional(:blue) => String.t() }
Configuration for an indicator
Specify the Linux LED name for each LED. Single LED indicators should use a
color that's close or just choose :red
.
@type indicator_name() :: atom()
The name for one indicator
An indicator may be composed of multiple LEDs, but they're arranged such that it looks like one light source to someone looking at it. For example, an RGB LED has 3 LEDs inside of it.
These can be anything you want. If you don't explicitly specify indicator
names, an indicator named :default
is used.
@type options() :: [ led_path: String.t(), slots: [slot()], indicators: %{required(indicator_name()) => indicator_config()}, name: atom() | nil, backend: keyword() ]
Delux configuration options
:indicators
- a map of indicator names to their configurations:slots
- a list of slot atoms from lowest to highest priority. Defaults to[:status, :notification, :user_feedback]
:name
- register the Delux GenServer using this name. Defaults toDelux
. Specifynil
to not register a name.:backend
- options for the backend:led_path
- the path to the LED directories (defaults to"/sys/class/leds"
):hz
- the Linux kernel'sHZ
setting. Delux will adjust its timing based on this setting (defaults to 1000)
@type slot() :: atom()
A name of a slot for an indicator program
Slots determine which program is rendered when more than one can be
shown at the same time. The default slot is :status
which is also the
lowest priority slot. The :notification
and :user_feedback
slots are
higher priority. For example, rendering visual feedback to the user pressing a button
can be assigned to the :user_feedback
slot so the user knows that the
button pressed worked regardless of what else is happening.
Link to this section Functions
@spec adjust_brightness(GenServer.server(), 0..100) :: :ok
Adjust the overall brightness of all indicators
Effects are adjusted based on the value passed.
NOTE: This is not fully supported yet!
Returns a specification to start this module under a supervisor.
See Supervisor
.
@spec clear(GenServer.server(), slot()) :: :ok
Clear out all programs in the specified slot
The indicator is turned off if there are no programs in any slot.
@spec info() :: :ok
Call info/2
with the defaults
@spec info(indicator_name()) :: :ok
Call info/2
with the specified indicator
@spec info(GenServer.server(), indicator_name()) :: :ok
Print out info about an indicator
This is handy when you can't physically see an indicator. It's intended for
users at the IEx prompt. For programmatic use, see info_as_ansidata/2
.
@spec info_as_ansidata() :: IO.ANSI.ansidata()
Call info_as_ansidata/2
with the defaults
@spec info_as_ansidata(indicator_name()) :: IO.ANSI.ansidata()
Call info_as_ansidata/2
with the specified indicator
@spec info_as_ansidata(GenServer.server(), indicator_name()) :: IO.ANSI.ansidata()
Return user-readable information about an indicator
@spec render( %{required(indicator_name()) => Delux.Program.t() | nil} | Delux.Program.t() | nil ) :: :ok
Helper for rendering a program when using Delux's defaults
This calls render/3
using the default Delux GenServer and default slot.
@spec render( %{required(indicator_name()) => Delux.Program.t() | nil} | Delux.Program.t() | nil, slot() ) :: :ok
Helper for rendering a program to a slot
This calls render/3
using the default Delux GenServer.
@spec render( GenServer.server(), %{required(indicator_name()) => Delux.Program.t() | nil} | Delux.Program.t() | nil, slot() ) :: :ok
Update one or more indicators to a new program
Passing nil
for the program removes the program running in the specified
slot. This is the same as calling clear/2
.
@spec start_link(options()) :: GenServer.on_start()
Start an Delux GenServer
See t:options()
for configuration options