BTHome.Packet (BTHome v0.1.0)
View SourceBuilder pattern for creating BTHome v2 packets with a pipeable API.
This module provides a fluent interface for building BTHome v2 packets by accumulating measurements and then serializing them. It supports the builder pattern with method chaining using the pipe operator.
Examples
# Basic usage with builder pattern
{:ok, binary} = BTHome.new_packet()
|> BTHome.add_measurement(:temperature, 23.45)
|> BTHome.add_measurement(:motion, true)
|> BTHome.serialize()
# With encryption
{:ok, binary} = BTHome.new_packet()
|> BTHome.add_measurement(:temperature, 23.45)
|> BTHome.add_measurement(:humidity, 67.8)
|> BTHome.serialize(true)
# Error handling in the chain
result = BTHome.new_packet()
|> BTHome.add_measurement(:temperature, 23.45)
|> BTHome.add_measurement(:invalid_type, 42) # This will return an error
|> BTHome.serialize()
case result do
{:ok, binary} -> handle_success(binary)
{:error, error} -> handle_error(error)
end
Summary
Functions
Adds a measurement to the packet builder.
Creates a new empty packet builder.
Serializes the accumulated measurements in the packet.
Serializes the accumulated measurements in the packet, raising on error.
Types
@type t() :: %BTHome.Packet{ error: String.t() | nil, measurements: [BTHome.Measurement.t()] }
Functions
Adds a measurement to the packet builder.
If the packet already contains an error from a previous operation, this function will return the packet unchanged. Otherwise, it validates the measurement and adds it to the packet if valid.
Parameters
packet
- The packet builder structtype
- The measurement type atomvalue
- The measurement valueopts
- Optional keyword list (same asBTHome.Measurement.new/3
)
Returns
The updated packet builder struct, potentially with an error if validation fails.
Examples
iex> packet = BTHome.new_packet()
iex> result = BTHome.add_measurement(packet, :temperature, 23.45)
iex> length(result.measurements)
1
iex> is_nil(result.error)
true
iex> packet = BTHome.new_packet()
iex> result = BTHome.add_measurement(packet, :invalid_type, 42)
iex> match?(%BTHome.Packet{measurements: [], error: "Unsupported measurement type: :invalid_type"}, result)
true
@spec new() :: t()
Creates a new empty packet builder.
Returns a new BTHome.Packet
struct that can be used to accumulate
measurements using the builder pattern.
Returns
A new packet builder struct.
Examples
iex> BTHome.new_packet()
%BTHome.Packet{measurements: [], error: nil}
Serializes the accumulated measurements in the packet.
Parameters
packet
- The packet builder structopts
- Serialization options (keyword list):encrypt
- Encryption options (keyword list or map):key
- 16-byte encryption key (required):mac_address
- 6-byte MAC address (required):counter
- 4-byte counter value (required)
Returns
{:ok, binary}
on success, {:error, reason}
on failure.
Examples
# Basic usage
iex> {:ok, binary} = BTHome.new_packet()
iex> |> BTHome.add_measurement(:temperature, 23.45)
iex> |> BTHome.serialize()
iex> is_binary(binary)
true
# With encryption
iex> key = <<1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16>>
iex> mac = <<0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF>>
iex> opts = [encrypt: [key: key, mac_address: mac, counter: 1]]
iex> {:ok, binary} = BTHome.new_packet()
iex> |> BTHome.add_measurement(:temperature, 23.45)
iex> |> BTHome.serialize(opts)
iex> is_binary(binary)
true
Serializes the accumulated measurements in the packet, raising on error.
Similar to serialize/2
but raises an exception instead of returning an error tuple.
This is useful for pipeline operations where you want to fail fast on errors.
Parameters
packet
- The packet builder structopts
- Serialization options (same asserialize/2
)
Returns
Binary BTHome v2 data on success, raises on error.
Examples
# Basic usage
iex> binary = BTHome.new_packet()
iex> |> BTHome.add_measurement(:temperature, 23.45)
iex> |> BTHome.serialize!()
iex> is_binary(binary)
true
# With encryption
iex> key = <<1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16>>
iex> mac = <<0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF>>
iex> opts = [encrypt: [key: key, mac_address: mac, counter: 1]]
iex> binary = BTHome.new_packet()
iex> |> BTHome.add_measurement(:temperature, 23.45)
iex> |> BTHome.serialize!(opts)
iex> is_binary(binary)
true
Raises
ArgumentError
if serialization fails or packet contains an error.