defmodule Grizzly.ZWave.Commands.SensorMultilevelReport do
@moduledoc """
This module implements command COMMAND_CLASS_SENSOR_MULTILEVEL implements the
SENSOR_MULTILEVEL_REPORT command class.
This command is used to advertise a multilevel sensor reading.
Params:
* `:sensor_type` - one of `:temperature`, `:illuminance`, `:power`, or
`:humidity` etc.(required)
* `:scale` - `0..3` - identifies a unit of measurement (required)
* `:value` - the sensed, numerical value (required)
"""
@behaviour Grizzly.ZWave.Command
alias Grizzly.ZWave.{Command, DecodeError, Encoding}
alias Grizzly.ZWave.CommandClasses.SensorMultilevel
# See Grizzly.ZWave.CommandClasses.SensorMultilevel for the full list of sensor type values
@type sensor_type :: atom
@type param ::
{:sensor_type, sensor_type} | {:scale, 0..3} | {:value, number}
@impl true
@spec new([param()]) :: {:ok, Command.t()}
def new(params) do
command = %Command{
name: :sensor_multilevel_report,
command_byte: 0x05,
command_class: SensorMultilevel,
params: params,
impl: __MODULE__
}
{:ok, command}
end
@impl true
def encode_params(command) do
sensor_type_byte = SensorMultilevel.encode_sensor_type(Command.param!(command, :sensor_type))
scale = Command.param!(command, :scale)
value = Command.param!(command, :value)
{int_value, precision, byte_size} = Encoding.encode_zwave_float(value)
<<
sensor_type_byte,
precision::size(3),
scale::size(2),
byte_size::size(3),
int_value::signed-size(byte_size)-unit(8)
>>
end
@impl true
@spec decode_params(binary()) :: {:ok, [param()]} | {:error, DecodeError.t()}
def decode_params(<<
sensor_type_byte,
precision::size(3),
scale::size(2),
size::size(3),
int_value::signed-size(size)-unit(8)
>>) do
with {:ok, sensor_type} <- SensorMultilevel.decode_sensor_type(sensor_type_byte) do
value = Encoding.decode_zwave_float(int_value, precision)
{:ok, [sensor_type: sensor_type, scale: scale, value: value]}
else
{:error, %DecodeError{}} = error ->
error
end
end
end