View Source Delux (delux v0.1.2)

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
  • Program priority - a user-provided name that determines which program is run when multiple are scheduled. For example, a program that gives the user feedback for pressing a button could take precedence over a program showing network connection status

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> {:ok, pid} = Delux.start_link(indicators: %{default: %{green: "led0"}})
iex> Delux.render(pid, Delux.Effects.blink(:green, 2))
iex> Delux.info(pid)
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/3 function creates a 2 Hz blinking program for Delux to render. With nothing else specified, Delux.render/2 runs the program on the default indicator at the default priority.

Link to this section Summary

Types

Configuration for an indicator

The name for one indicator

Delux configuration options

Priority of an indicator program

Functions

Adjust the overall brightness of all indicators

Returns a specification to start this module under a supervisor.

Clear out any programs set at the specified priority

Print out info about an indicator

Return user-readable information about an indicator

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(),
  priorities: [priority()],
  indicators: %{required(indicator_name()) => indicator_config()},
  name: atom()
]

Delux configuration options

  • :led_path - the path to the LED directories (defaults to "/sys/class/leds")
  • :priorities - a list of priority atoms from lowest to highest. Defaults to [:status, :notification, :user_feedback]
  • :indicators - a map of indicator names to their configurations
  • :name - if specified, this is passed to GenServer.start_link/3 so register the name of the Delux GenServer
@type priority() :: atom()

Priority of an indicator program

Priorities determine which program is rendered when more than one can be shown at the same time. The default priority is :status which is also the lowest priority. The :notification and :user_feedback priorities are higher. For example, rendering visual feedback to the user pressing a button can be assigned to the :user_feedback priority so the user knows that the button pressed worked regardless of what else is happening.

Link to this section Functions

Link to this function

adjust_brightness(server, percent)

View Source
@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.

Link to this function

clear(server, priority \\ :status)

View Source
@spec clear(GenServer.server(), priority()) :: :ok

Clear out any programs set at the specified priority

If this means that no programs at any priority are set, the indicator is turned off.

Link to this function

info(server, indicator \\ :default)

View Source

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.

Link to this function

info_as_ansidata(server, indicator \\ :default)

View Source
@spec info_as_ansidata(GenServer.server(), indicator_name()) :: IO.ANSI.ansidata()

Return user-readable information about an indicator

Link to this function

render(server, program, priority \\ :status)

View Source
@spec render(
  GenServer.server(),
  %{required(indicator_name()) => Delux.Program.t() | nil}
  | Delux.Program.t()
  | nil,
  priority()
) :: :ok

Update one or more indicators to a new program

Passing nil for the program removes the program running at the specified priority. 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