GoveeLights.Device.State (Govee Lights v0.2.0)
View SourceRepresents the normalized state of a Govee device.
This struct wraps a subset of the state we care about in a typed way, while still allowing the rest of the raw API payload to be handled elsewhere if needed.
Fields:
:on– whether the device is on, or:unknownif the API didn't say.:brightness– brightness level (0..100), or:unknown.:color– RGB map like%{r: 255, g: 255, b: 255}, or:unknown.:last_checked– timestamp of the last known state update (ornilif not provided yet).
The new/1 constructor expects a map with atom keys and uses
GoveeLights.Utils helpers to validate values. You can extend it over
time to parse more fields as you discover them.
Examples
Minimal state (no keys provided):
iex> {:ok, state} = GoveeLights.Device.State.new(%{})
iex> state.on
:unknown
iex> state.brightness
:unknown
iex> state.color
:unknown
iex> state.last_checked
nilWith basic fields:
iex> {:ok, state} =
...> GoveeLights.Device.State.new(%{
...> on: true,
...> brightness: 42
...> })
iex> state.on
true
iex> state.brightness
42
iex> state.color
:unknownWith a valid RGB color and last_checked timestamp:
iex> ts = ~U[2025-01-02 12:00:00Z]
iex> {:ok, state} =
...> GoveeLights.Device.State.new(%{
...> on: true,
...> brightness: 100,
...> color: %{r: 255, g: 128, b: 0},
...> last_checked: ts
...> })
iex> state.color
%{r: 255, g: 128, b: 0}
iex> state.last_checked == ts
trueInvalid on value (delegated to GoveeLights.Utils.fetch_optional_boolean/3):
iex> GoveeLights.Device.State.new(%{on: "yes"})
{:error, {:invalid_boolean, :on, "yes"}}Invalid brightness:
iex> GoveeLights.Device.State.new(%{brightness: -1})
{:error, {:invalid_brightness, -1}}
iex> GoveeLights.Device.State.new(%{brightness: 200})
{:error, {:invalid_brightness, 200}}Invalid color shape / values:
iex> GoveeLights.Device.State.new(%{color: %{r: 0, g: 0}})
{:error, {:invalid_color, %{r: 0, g: 0}, "expected a map with r, g, b"}}
iex> GoveeLights.Device.State.new(%{color: %{r: 999, g: 0, b: 0}})
{:error, {:invalid_color, %{r: 999, g: 0, b: 0}, "expected r, g, b in 0..255"}}
iex> GoveeLights.Device.State.new(%{color: "not-a-map"})
{:error, {:invalid_color, "not-a-map"}}
Summary
Functions
Builds a new Elixir.GoveeLights.Device.State struct from a map with atom keys.
Types
@type color_rgb() :: %{ r: non_neg_integer(), g: non_neg_integer(), b: non_neg_integer() }
@type t() :: %GoveeLights.Device.State{ brightness: non_neg_integer() | :unknown, color: color_rgb() | :unknown, last_checked: DateTime.t() | nil, on: boolean() | :unknown }
Functions
Builds a new Elixir.GoveeLights.Device.State struct from a map with atom keys.
It normalizes optional fields and returns either {:ok, state} or
{:error, reason}. See the moduledoc for detailed examples.