-
Notifications
You must be signed in to change notification settings - Fork 9
/
meter_supported_report.ex
112 lines (95 loc) · 3.58 KB
/
meter_supported_report.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
defmodule Grizzly.ZWave.Commands.MeterSupportedReport do
@moduledoc """
This module implement command METER_SUPPORTED_REPORT of command class METER.
This command is used to advertise the supported scales and metering capabilities of the sending node.
## Parameters
* `:meter_reset_supported` - whether the node supports the METER_RESET command (required)
* `:meter_type` - the implemented meter type (required)
* `:supported_scales` - the supported scales (required)
* `:rate_type` - the supported rate type (v4+)
"""
@behaviour Grizzly.ZWave.Command
alias Grizzly.ZWave.{Command, DecodeError}
alias Grizzly.ZWave.CommandClasses.Meter
@type param :: {:meter_reset, any()} | {:meter_type, any()} | {:scale_supported, any()}
@impl Grizzly.ZWave.Command
@spec new([param()]) :: {:ok, Command.t()}
def new(params) do
command = %Command{
name: :meter_supported_report,
command_byte: 0x04,
command_class: Meter,
params: params,
impl: __MODULE__
}
{:ok, command}
end
@impl Grizzly.ZWave.Command
@spec encode_params(Command.t()) :: binary()
def encode_params(command) do
meter_reset_supported_bit =
if Command.param!(command, :meter_reset_supported) == true, do: 1, else: 0
meter_type = Command.param!(command, :meter_type)
meter_type_bin = Meter.encode_meter_type(meter_type)
supported_scales = Command.param!(command, :supported_scales)
rate_type_bin =
case Command.param(command, :rate_type) do
nil -> 0
rate_type -> Meter.encode_rate_type(rate_type)
end
{scales_bitmask1, scales_bitmask2} =
Meter.encode_supported_scales_bitmasks(supported_scales, meter_type)
if scales_bitmask2 == 0 do
<<meter_reset_supported_bit::1, rate_type_bin::2, meter_type_bin::5, scales_bitmask1>>
else
<<meter_reset_supported_bit::1, rate_type_bin::2, meter_type_bin::5, 1::1,
scales_bitmask1::7, 1, scales_bitmask2>>
end
end
@impl Grizzly.ZWave.Command
@spec decode_params(binary()) :: {:ok, [param()]} | {:error, DecodeError.t()}
def decode_params(
<<meter_reset_supported_bit::1, rate_type_bin::2, meter_type_bin::5, scales_bitmask1::8>>
) do
with {:ok, rate_type} <- Meter.decode_rate_type(rate_type_bin),
{:ok, meter_type} <- Meter.decode_meter_type(meter_type_bin),
{:ok, supported_scales} =
Meter.decode_supported_scales_bitmasks({<<scales_bitmask1>>, <<0>>}, meter_type) do
meter_reset_supported = meter_reset_supported_bit == 1
{:ok,
[
meter_reset_supported: meter_reset_supported,
meter_type: meter_type,
rate_type: rate_type,
supported_scales: supported_scales
]}
else
{:error, %DecodeError{}} = error ->
error
end
end
def decode_params(
<<meter_reset_supported_bit::1, rate_type_bin::2, meter_type_bin::5, 1::1,
scales_bitmask1::7, 1, scales_bitmask2::binary>>
) do
with {:ok, rate_type} <- Meter.decode_rate_type(rate_type_bin),
{:ok, meter_type} <- Meter.decode_meter_type(meter_type_bin),
{:ok, supported_scales} =
Meter.decode_supported_scales_bitmasks(
{<<scales_bitmask1>>, scales_bitmask2},
meter_type
) do
meter_reset_supported = meter_reset_supported_bit == 1
{:ok,
[
meter_reset_supported: meter_reset_supported,
meter_type: meter_type,
rate_type: rate_type,
supported_scales: supported_scales
]}
else
{:error, %DecodeError{}} = error ->
error
end
end
end