GoveeLights.Device (Govee Lights v0.2.0)

View Source

Represents a single Govee light device.

This module defines a typed struct and a smart constructor new/1 that validates and normalizes input coming from Govee's API responses or internal code.

Fields

  • :idrequired. Govee device identifier (MAC-like string).
  • :modelrequired. Govee model identifier (e.g. "H6008").
  • :name – optional, user-friendly name for the device (or nil).
  • :state – normalized device state as GoveeLights.Device.State.t(). When no state map is provided, a default state with :unknown values is used.
  • :properties – map for additional device properties (defaults to %{}).
  • :controllable – boolean flag indicating whether the device can be controlled by the API (defaults to false).

The new/1 function accepts either a map or a keyword list, with string or atom keys. Unknown keys are ignored. All validation happens in new/1 / new_internal/1.

Examples

Minimal valid device using atom keys:

iex> {:ok, device} =
...>   GoveeLights.Device.new(%{id: "AA:BB:CC:DD:EE:FF:11:22", model: "H6008"})
iex> device.id
"AA:BB:CC:DD:EE:FF:11:22"
iex> device.model
"H6008"
iex> device.name
nil
iex> match?(%GoveeLights.Device.State{}, device.state)
true
iex> device.state.on
:unknown
iex> device.properties
%{}
iex> device.controllable
false

Using a keyword list (e.g. from internal code):

iex> {:ok, device} =
...>   GoveeLights.Device.new(
...>     id: "AA:BB:CC:DD:EE:FF:11:22",
...>     model: "H6008",
...>     name: "Backrooms",
...>     controllable: true
...>   )
iex> device.name
"Backrooms"
iex> device.controllable
true

Using string keys (e.g. decoded JSON from the Govee API):

iex> {:ok, device} =
...>   GoveeLights.Device.new(%{
...>     "id" => "AA:BB:CC:DD:EE:FF:11:22",
...>     "model" => "H6008",
...>     "name" => "Bedroom",
...>     "state" => %{
...>       on: true,
...>       brightness: 42
...>     }
...>   })
iex> device.id
"AA:BB:CC:DD:EE:FF:11:22"
iex> device.model
"H6008"
iex> device.name
"Bedroom"
iex> device.state.on
true
iex> device.state.brightness
42

Error when required fields are missing:

iex> GoveeLights.Device.new(%{model: "H6008"})
{:error, {:missing, :id}}

iex> GoveeLights.Device.new(%{id: "AA:BB:CC:DD:EE:FF:11:22"})
{:error, {:missing, :model}}

Error when passing a non-keyword list:

iex> GoveeLights.Device.new([1, 2, 3])
{:error, {:invalid_attrs, :expected_keyword_list}}

Error when the input is neither a map nor a keyword list:

iex> GoveeLights.Device.new("not-a-map-or-keyword-list")
{:error, {:invalid_attrs, :expected_map_or_keyword_list}}

Summary

Functions

Builds a new Elixir.GoveeLights.Device struct from a map or keyword list.

Types

new_error()

@type new_error() ::
  {:missing, atom()}
  | {:invalid_string, atom(), term()}
  | {:invalid_map, atom(), term()}
  | {:invalid_boolean, atom(), term()}
  | {:invalid_attrs, term()}
  | GoveeLights.Device.State.new_error()

t()

@type t() :: %GoveeLights.Device{
  controllable: boolean(),
  id: String.t(),
  model: String.t(),
  name: String.t() | nil,
  properties: map(),
  state: GoveeLights.Device.State.t()
}

Functions

new(attrs)

@spec new(map() | keyword()) :: {:ok, t()} | {:error, new_error()}

Builds a new Elixir.GoveeLights.Device struct from a map or keyword list.

Accepted inputs:

  • a map with atom and/or string keys
  • a keyword list (list of {atom, value} pairs)

Validation rules:

  • :id and :model must be present and non-empty strings.
  • :name is optional and may be nil or a (possibly empty) string.
  • :state may be omitted or provided as a map; when present it must be a map suitable for GoveeLights.Device.State.new/1.
  • :properties must be a map when present; otherwise defaults to %{}.
  • :controllable must be boolean when present; otherwise defaults to false.

On success, returns {:ok, %Elixir.GoveeLights.Device{}}. On failure, returns {:error, reason} where reason is one of the new_error/0 variants.