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 defaults

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 to Delux. Specify nil 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's HZ 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

Link to this function

adjust_brightness(server \\ __MODULE__, 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 \\ __MODULE__, slot \\ :status)

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

Link to this function

info_as_ansidata(indicator)

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

Call info_as_ansidata/2 with the specified indicator

Link to this function

info_as_ansidata(server, indicator)

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

Link to this function

render(server, program, slot)

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