/
device_class.ex
127 lines (118 loc) · 3.75 KB
/
device_class.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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
defmodule Grizzly.ZWave.DeviceClass do
@moduledoc """
Z-Wave device classes
Z-Wave device classes allow grouping devices with the same functionality
together. Moreover, the device class specification for specific device classes
provide mandatory and recommended command class support.
"""
alias Grizzly.ZWave.Commands.VersionReport
alias Grizzly.ZWave.{CommandClasses, DeviceClasses}
@type command_class_version() :: integer()
@type command_class_spec() :: %{
support: %{required(CommandClasses.command_class()) => command_class_version()},
control: %{required(CommandClasses.command_class()) => command_class_version()}
}
@type t() :: %{
basic_device_class: DeviceClasses.basic_device_class(),
generic_device_class: DeviceClasses.generic_device_class(),
specific_device_class: DeviceClasses.specific_device_class(),
command_classes: command_class_spec(),
manufacturer_id: non_neg_integer(),
product_id: non_neg_integer(),
product_type_id: non_neg_integer(),
library_type: VersionReport.library_type()
}
@doc """
Get the command class version for the command class
"""
@spec get_command_class_version(t(), CommandClasses.command_class()) :: non_neg_integer() | nil
def get_command_class_version(device_class, command_class) do
device_class.command_classes.control
|> Map.merge(device_class.command_classes.support)
|> Enum.find_value(fn
{^command_class, version} -> version
_ -> nil
end)
end
@doc """
Check if the device class specification includes a particular command class
"""
@spec has_command_class?(t(), CommandClasses.command_class()) :: boolean()
def has_command_class?(device_class, command_class) do
device_class.command_classes.control
|> Map.merge(device_class.command_classes.support)
|> Enum.find_value(fn
{^command_class, _version} -> true
_ -> false
end)
end
@doc """
A device class for a HVAC thermostat
"""
@spec thermostat_hvac() :: t()
def thermostat_hvac() do
%{
basic_device_class: :routing_slave,
generic_device_class: :thermostat,
specific_device_class: :thermostat_general_v2,
command_classes: %{
support: %{
alarm: 3,
association: 2,
association_group_information: 1,
basic: 1,
battery: 1,
device_reset_locally: 1,
manufacturer_specific: 2,
power_level: 1,
security_2: 1,
supervision: 1,
thermostat_mode: 3,
thermostat_fan_mode: 1,
thermostat_fan_state: 1,
thermostat_setpoint: 2,
transport_service: 2,
sensor_multilevel: 5,
version: 2,
zwave_plus_info: 2
},
control: %{}
},
manufacturer_id: 0x0000,
product_id: 0x0000,
product_type_id: 0x0000,
library_type: :routing_slave
}
end
@doc """
Device class spec for a generic multilevel sensor
"""
@spec multilevel_sensor() :: t()
def multilevel_sensor() do
%{
basic_device_class: :routing_slave,
generic_device_class: :sensor_multilevel,
specific_device_class: :routing_sensor_multilevel,
command_classes: %{
support: %{
alarm: 3,
association: 2,
association_group_information: 1,
basic: 1,
battery: 1,
device_reset_locally: 1,
manufacturer_specific: 2,
security_2: 1,
sensor_multilevel: 5,
version: 2,
zwave_plus_info: 2
},
control: %{}
},
manufacturer_id: 0x0000,
product_id: 0x0000,
product_type_id: 0x0000,
library_type: :routing_slave
}
end
end