Utility functions for encoding/decoding common data types.
Summary
Types
Common representation for durations used in Z-Wave command classes.
Functions
Converts a bit into a boolean.
Converts a boolean into a bit.
Decodes an indexed bitmask.
Decodes a duration as encoded by encode_duration/1. Returns :unknown if
the value is outside the range 0x00..0xFD or :default for 0xFF.
Decodes a list of keys from a bitmask using the provided Grizzly.ZWave.ZWEnum
to map keys to bit positions.
Decodes a 128-bit binary into an IPv6 address tuple.
Decodes a binary string into a UTF-8 string using the specified encoding type.
Decodes a string encoding type from a byte value.
Converts an integer value and non-zero precision into a float by dividing the
integer by 10 ^ precision. If the given precision is zero, the integer is
returned as-is.
Encodes a list into a bitmask.
Encodes a duration in seconds into a duration byte.
Encodes a list of keys into a bitmask using the provided Grizzly.ZWave.ZWEnum
to map keys to bit positions.
Encodes an IPv6 address tuple into a 128-bit binary.
Encodes a UTF-8 string using the specified encoding type.
Encodes a string encoding type to a byte value.
Converts a float into a tuple containing an integer representation of the float, the factor of 10 by which the integer must be divided to get the original float, and the number of bytes needed to represent the value as a signed integer.
Reduce over a binary by repeatedly applying a reducer function until the binary is empty.
Reduce over a binary by repeatedly applying a reducer function.
Converts a float into a binary representation of a Z-Wave float according to the typical format.
Types
@type duration() :: 0..7560 | :unknown | :default
Common representation for durations used in Z-Wave command classes.
Durations of 0..127 seconds are encoded with 1-second resolution. Durations of 128..7560 seconds are encoded with 1-minute resolution. Larger durations are not supported and will be encoded as unknown (0xFE).
See section 2.1.7.3 of the Z-Wave Specification for details.
@type encode_bitmask_opts() :: [{:min_bytes, non_neg_integer()}]
@type string_encoding() :: :ascii | :extended_ascii | :utf16
Functions
@spec binary_sensor_types() :: Grizzly.ZWave.ZWEnum.t()
@spec bit_to_bool(0 | 1) :: boolean()
Converts a bit into a boolean.
Examples
iex> bit_to_bool(1)
true
iex> bit_to_bool(0)
false
@spec bool_to_bit(boolean()) :: 0 | 1
Converts a boolean into a bit.
Examples
iex> bool_to_bit(true)
1
iex> bool_to_bit(false)
0
@spec decode_bitmask(binary()) :: [non_neg_integer()]
Decodes an indexed bitmask.
Examples
iex> decode_bitmask(<<>>)
[]
iex> decode_bitmask(<<0b10110001, 0, 0>>)
[0, 4, 5, 7]
iex> decode_bitmask(<<0b10110001, 0b00000001, 0, 0, 0b00001000>>)
[0, 4, 5, 7, 8, 35]
Decodes a duration as encoded by encode_duration/1. Returns :unknown if
the value is outside the range 0x00..0xFD or :default for 0xFF.
Examples
iex> decode_duration(0x00)
0
iex> decode_duration(0x2D)
45
iex> decode_duration(0x7F)
127
iex> decode_duration(0x80)
60
iex> decode_duration(0x81)
120
iex> decode_duration(0x82)
180
iex> decode_duration(0xFD)
7560
iex> decode_duration(0xFE)
:unknown
iex> decode_duration(0xFF)
:default
@spec decode_enum_bitmask(Grizzly.ZWave.ZWEnum.t(), bitstring()) :: [ Grizzly.ZWave.ZWEnum.k() ]
Decodes a list of keys from a bitmask using the provided Grizzly.ZWave.ZWEnum
to map keys to bit positions.
Examples
iex> enum = Grizzly.ZWave.ZWEnum.new(foo: 1, bar: 2, baz: 7, qux: 8)
iex> decode_enum_bitmask(enum, <<0b10000010, 0b1>>)
[:foo, :baz, :qux]
@spec decode_ipv6_address(binary()) :: :inet.ip6_address()
Decodes a 128-bit binary into an IPv6 address tuple.
Examples
iex> decode_ipv6_address(<<0xfd00::16, 0xaaaa::16, 0::16, 0::16, 0::16, 0::16, 0::16, 2::16>>)
{0xfd00, 0xaaaa, 0, 0, 0, 0, 0, 2}
@spec decode_string(binary(), string_encoding()) :: binary()
Decodes a binary string into a UTF-8 string using the specified encoding type.
@spec decode_string_encoding(byte()) :: string_encoding() | :unknown
Decodes a string encoding type from a byte value.
@spec decode_zwave_float(integer(), non_neg_integer()) :: number()
Converts an integer value and non-zero precision into a float by dividing the
integer by 10 ^ precision. If the given precision is zero, the integer is
returned as-is.
Examples
iex> decode_zwave_float(0, 0)
0
iex> decode_zwave_float(0, 2)
0.0
iex> decode_zwave_float(1234, 2)
12.34
iex> decode_zwave_float(1234, 1)
123.4
iex> decode_zwave_float(1234, 0)
1234
iex> decode_zwave_float(-1234, 2)
-12.34
@spec door_lock_modes() :: Grizzly.ZWave.ZWEnum.t()
@spec encode_bitmask([non_neg_integer()], encode_bitmask_opts()) :: binary()
Encodes a list into a bitmask.
Examples
iex> encode_bitmask([])
<<>>
iex> encode_bitmask([0, 4, 5, 7, 8, 35])
<<0b10110001, 0b00000001, 0, 0, 0b00001000>>
iex> encode_bitmask([31, 8, 5, 0, 4, 7])
<<0b10110001, 0b00000001, 0b00000000, 0b10000000>>
iex> encode_bitmask([0, 4, 5, 7], min_bytes: 3)
<<0b10110001, 0, 0>>
Encodes a duration in seconds into a duration byte.
Durations of 0..127 seconds are encoded with 1-second resolution. Durations of 128..7560 seconds are encoded with 1-minute resolution, rounded to the nearest minute. Larger durations are not supported and will be encoded as unknown (0xFE).
Some command classes also support a device-default duration (0xFF), which can
be specified using :default.
Examples
iex> encode_duration(0)
0x00
iex> encode_duration(45)
0x2D
iex> encode_duration(127)
0x7F
iex> encode_duration(128)
0x81
iex> encode_duration(180)
0x82
iex> encode_duration(200)
0x82
iex> encode_duration(7560)
0xFD
iex> encode_duration(8000)
0xFE
iex> encode_duration(:unknown)
0xFE
iex> encode_duration(:default)
0xFF
@spec encode_enum_bitmask( Grizzly.ZWave.ZWEnum.t(), [Grizzly.ZWave.ZWEnum.k()], encode_bitmask_opts() ) :: bitstring()
Encodes a list of keys into a bitmask using the provided Grizzly.ZWave.ZWEnum
to map keys to bit positions.
Examples
iex> enum = Grizzly.ZWave.ZWEnum.new(foo: 1, bar: 2, baz: 7, qux: 8)
iex> encode_enum_bitmask(enum, [:foo, :baz, :qux])
<<0b10000010, 0b1>>
@spec encode_ipv6_address(:inet.ip6_address()) :: binary()
Encodes an IPv6 address tuple into a 128-bit binary.
Examples
iex> encode_ipv6_address({0xfd00, 0xaaaa, 0, 0, 0, 0, 0, 2})
<<0xfd00::16, 0xaaaa::16, 0::16, 0::16, 0::16, 0::16, 0::16, 2::16>>
@spec encode_string(binary(), string_encoding()) :: binary()
Encodes a UTF-8 string using the specified encoding type.
ASCII and extended ASCII encodings remove non-ASCII characters, while UTF-16 encoding converts the string to a UTF-16 binary representation.
@spec encode_string_encoding(string_encoding()) :: byte()
Encodes a string encoding type to a byte value.
Uses the representation defined in the Node Naming and User Credential command classes.
@spec encode_zwave_float(value :: number()) :: {int_value :: integer(), precision :: non_neg_integer(), size :: integer()}
Converts a float into a tuple containing an integer representation of the float, the factor of 10 by which the integer must be divided to get the original float, and the number of bytes needed to represent the value as a signed integer.
Examples
iex> encode_zwave_float(0)
{0, 0, 1}
iex> encode_zwave_float(-1.5)
{-15, 1, 1}
iex> encode_zwave_float(-1.50)
{-15, 1, 1}
iex> encode_zwave_float(128)
{128, 0, 2}
iex> encode_zwave_float(127.5)
{1275, 1, 2}
iex> encode_zwave_float(-75.25)
{-7525, 2, 2}
iex> encode_zwave_float(-752.55)
{-75255, 2, 4}
iex> encode_zwave_float(-75.255)
{-75255, 3, 4}
@spec humidity_control_modes() :: Grizzly.ZWave.ZWEnum.t()
@spec humidity_control_operating_states() :: Grizzly.ZWave.ZWEnum.t()
@spec humidity_control_setpoint_scales() :: Grizzly.ZWave.ZWEnum.t()
@spec humidity_control_setpoint_types() :: Grizzly.ZWave.ZWEnum.t()
@spec kex_fail_types() :: Grizzly.ZWave.ZWEnum.t()
@spec multilevel_sensor_types() :: Grizzly.ZWave.ZWEnum.t()
@spec network_update_request_statuses() :: Grizzly.ZWave.ZWEnum.t()
@spec power_levels() :: Grizzly.ZWave.ZWEnum.t()
@spec reduce_binary(binary(), term(), (binary(), acc :: term() -> {acc :: term(), rest :: binary()})) :: acc :: term()
Reduce over a binary by repeatedly applying a reducer function until the binary is empty.
The reducer function should take a binary and an accumulator and return a tuple
{new_acc, rest} where new_acc is the updated accumulator and rest is the
remaining binary to process.
Examples
iex> reducer = fn
...> <<word::16, rest::binary>>, acc ->
...> {[word | acc], rest}
...> <<byte, rest::binary>>, acc ->
...> {[byte | acc], rest}
...> end
iex> reduce_binary(<<1, 2, 3>>, [], reducer)
[3, 258]
@spec reduce_binary_while(binary(), term(), (binary(), acc :: term() -> {:halt | :cont, {acc :: term(), rest :: binary()}})) :: {acc :: term(), rest :: binary()}
Reduce over a binary by repeatedly applying a reducer function.
The reducer function should take a binary and an accumulator and return either
{:cont, {new_acc, rest}} to continue reducing with the new accumulator and
remaining binary, or {:halt, {new_acc, rest}} to stop reducing and return the
final accumulator and remaining binary.
The reduction will halt automatically when the binary is empty.
Examples
iex> reducer = fn
...> <<byte, rest::binary>>, acc when byte < 5 ->
...> {:cont, {[byte | acc], rest}}
...> binary, acc ->
...> {:halt, {acc, binary}}
...> end
iex> reduce_binary_while(<<1, 2, 3, 6, 4>>, [], reducer)
{[3, 2, 1], <<6, 4>>}
iex> reduce_binary_while(<<1, 2, 3>>, reducer)
{[3, 2, 1], <<>>}
@spec security_key_types() :: Grizzly.ZWave.ZWEnum.t()
@spec thermostat_fan_modes() :: Grizzly.ZWave.ZWEnum.t()
@spec thermostat_fan_states() :: Grizzly.ZWave.ZWEnum.t()
@spec tz_offset_signs() :: Grizzly.ZWave.ZWEnum.t()
@spec uc_admin_pin_code_set_statuses() :: Grizzly.ZWave.ZWEnum.t()
@spec uc_association_set_statuses() :: Grizzly.ZWave.ZWEnum.t()
@spec uc_credential_types() :: Grizzly.ZWave.ZWEnum.t()
@spec user_code_keypad_modes() :: Grizzly.ZWave.ZWEnum.t()
Converts a float into a binary representation of a Z-Wave float according to the typical format.
- precision (3 bits)
- scale (2 bits)
- size (3 bits)
- value (n bytes, where n = size)