Fledex.LedStrip (fledex v0.5.0)

View Source

This module defines a GenServer that manages the LED strip (be it a real one with the Fledex.Driver.Impl.Spi or a virtual one with e.g. the Fledex.Driver.Impl.Kino).

You would start an LedStrip for every led strip you have.

The Fledex.LedStrip will take several Fledex.Leds definitions and merge them together to be displayed on a single LED strip.

The role the LedStrip plays is similar to the one a window server plays on a normal computer, except that a window server would manage several screens, whereas here each LED strip would get its own.

Summary

Functions

Change some aspect of a configuration for a specific strip. The configuration will be updated and the old values will be returned.

Returns a specification to start this module under a supervisor.

Drop a previously defined namespace.

Checks whether the specified namespace already exists

In some circumstances it might be necessary to reinitialize the led_strip (including the drivers). Most of the time you don't need to call this. If you do, you will surely know about it :)

Sets the leds in a specific strip and namespace.

This starts the server controlling a specfic led strip. It is possible to install several drivers at the same time, so different hardware gets the same data at the same time (similar to mirroring a screen). If you want to send different data to different strips, you should start several instances of this server

Types

Functions

change_config(strip_name, global_config)

@spec change_config(
  atom(),
  keyword()
) :: {:ok, [keyword()]}

Change some aspect of a configuration for a specific strip. The configuration will be updated and the old values will be returned.

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

define_namespace(strip_name, namespace)

@spec define_namespace(atom(), atom()) :: :ok | {:error, String.t()}

Define a new namespace

drop_namespace(strip_name, namespace)

@spec drop_namespace(atom(), atom()) :: :ok

Drop a previously defined namespace.

exist_namespace(strip_name, namespace)

@spec exist_namespace(atom(), atom()) :: boolean()

Checks whether the specified namespace already exists

init_config(updates)

@spec init_config(keyword()) :: config_t()

reinit(strip_name, driver, strip_config)

@spec reinit(
  atom(),
  module() | {module(), keyword()} | [{module(), keyword()}],
  keyword()
) :: :ok

In some circumstances it might be necessary to reinitialize the led_strip (including the drivers). Most of the time you don't need to call this. If you do, you will surely know about it :)

set_leds(strip_name, namespace, leds)

@spec set_leds(atom(), atom(), [pos_integer()]) :: :ok | {:error, String.t()}

Sets the leds in a specific strip and namespace.

Note: repeated calls of this function will result in previously set leds will be overwritten. We are passing a list of leds which means every led will be rewritten, except if we define a 'shorter" led sequence. In that case some leds might retain their previously set value.

start_link(strip_name, driver \\ Null, global_config \\ [])

@spec start_link(
  atom(),
  module() | {module(), keyword()} | [{module(), keyword()}],
  keyword()
) ::
  start_link_response()

This starts the server controlling a specfic led strip. It is possible to install several drivers at the same time, so different hardware gets the same data at the same time (similar to mirroring a screen). If you want to send different data to different strips, you should start several instances of this server

Because we can have several drivers (even though that is rather the exception) the confirgation is split up into several parts (not all of them need to be present):

  • The name of the strip (mandatory)
  • The global configuration of the strip (optional, defaults will be used if not specified)
  • A driver module (that also provides a default set of configs)
  • A list of detailed configs that are overlayed over the defaults. This allows for example to reuse the Fledex.Driver.Impl.Spi defaults, but change for example to a different spi device by setting :dev to spidev0.1

Here some examples (with aliased module names) how you can start the server:

  • Without real driver: start_link(:name)
  • With real driver: start_link(:name, Spi)
  • With some global config overlay and real driver: start_link(:name, Spi, timer_only_dirty_update: true)
  • With real driver and some driver overlay: start_link(:name, {Spi, dev: "spidev0.1"})
  • With several drivers: start_link(:name, [{Spu, []}, {Spi, dev: "spidev0.1"}])
  • With several drivers and global config: start_link(:name, [{Spi, []}, {Spi, dev: "spidev0.1"}], timer_only_dirty_update: true)

stop(strip_name)

@spec stop(GenServer.server()) :: :ok