Skip to content

Commit b0c7eb5

Browse files
Add support for additional Closure device types
This adds support for Coverings, Gate, Doors, and GarageDoors closure subtypes.
1 parent ca9c2e7 commit b0c7eb5

39 files changed

+2035
-36
lines changed

drivers/SmartThings/matter-switch/fingerprints.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4315,6 +4315,11 @@ matterGeneric:
43154315
- id: 0x002B # Fan
43164316
- id: 0x0110 # Mounted Dimmable Load Control
43174317
deviceProfileName: fan-modular
4318+
- id: "matter/closure"
4319+
deviceLabel: Matter Closure
4320+
deviceTypes:
4321+
- id: 0x0230 # Closure
4322+
deviceProfileName: window-covering-modular
43184323
- id: "matter/window/covering"
43194324
deviceLabel: Matter Window Covering
43204325
deviceTypes:
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
name: covering
2+
components:
3+
- id: main
4+
capabilities:
5+
- id: windowShade
6+
version: 1
7+
- id: battery
8+
version: 1
9+
optional: true
10+
- id: batteryLevel
11+
version: 1
12+
optional: true
13+
- id: firmwareUpdate
14+
version: 1
15+
- id: refresh
16+
version: 1
17+
categories:
18+
- name: Blind
19+
preferences:
20+
- preferenceId: reverse
21+
explicit: true
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: door
2+
components:
3+
- id: main
4+
capabilities:
5+
- id: doorControl
6+
version: 1
7+
- id: battery
8+
version: 1
9+
optional: true
10+
- id: batteryLevel
11+
version: 1
12+
optional: true
13+
- id: firmwareUpdate
14+
version: 1
15+
- id: refresh
16+
version: 1
17+
categories:
18+
- name: Door
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: garage-door
2+
components:
3+
- id: main
4+
capabilities:
5+
- id: doorControl
6+
version: 1
7+
- id: battery
8+
version: 1
9+
optional: true
10+
- id: batteryLevel
11+
version: 1
12+
optional: true
13+
- id: firmwareUpdate
14+
version: 1
15+
- id: refresh
16+
version: 1
17+
categories:
18+
- name: GarageDoor
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: gate
2+
components:
3+
- id: main
4+
capabilities:
5+
- id: doorControl
6+
version: 1
7+
- id: battery
8+
version: 1
9+
optional: true
10+
- id: batteryLevel
11+
version: 1
12+
optional: true
13+
- id: firmwareUpdate
14+
version: 1
15+
- id: refresh
16+
version: 1
17+
categories:
18+
- name: Door
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
local cluster_base = require "st.matter.cluster_base"
2+
local ClosureControlServerAttributes = require "embedded_clusters.ClosureControl.server.attributes"
3+
local ClosureControlServerCommands = require "embedded_clusters.ClosureControl.server.commands"
4+
local ClosureControlTypes = require "embedded_clusters.ClosureControl.types"
5+
6+
local ClosureControl = {}
7+
8+
ClosureControl.ID = 0x0104
9+
ClosureControl.NAME = "ClosureControl"
10+
ClosureControl.server = {}
11+
ClosureControl.client = {}
12+
ClosureControl.server.attributes = ClosureControlServerAttributes:set_parent_cluster(ClosureControl)
13+
ClosureControl.server.commands = ClosureControlServerCommands:set_parent_cluster(ClosureControl)
14+
ClosureControl.types = ClosureControlTypes
15+
16+
function ClosureControl:get_attribute_by_id(attr_id)
17+
local attr_id_map = {
18+
[0x0000] = "CountdownTime",
19+
[0x0001] = "MainState",
20+
[0x0002] = "CurrentErrorList",
21+
[0x0003] = "OverallCurrentState",
22+
[0x0004] = "OverallTargetState",
23+
[0x0005] = "LatchControlModes",
24+
[0xFFF9] = "AcceptedCommandList",
25+
[0xFFFB] = "AttributeList",
26+
}
27+
local attr_name = attr_id_map[attr_id]
28+
if attr_name ~= nil then
29+
return self.attributes[attr_name]
30+
end
31+
return nil
32+
end
33+
34+
function ClosureControl:get_server_command_by_id(command_id)
35+
local server_id_map = {
36+
[0x0000] = "Stop",
37+
[0x0001] = "MoveTo",
38+
[0x0002] = "Calibrate",
39+
}
40+
if server_id_map[command_id] ~= nil then
41+
return self.server.commands[server_id_map[command_id]]
42+
end
43+
return nil
44+
end
45+
46+
47+
ClosureControl.attribute_direction_map = {
48+
["CountdownTime"] = "server",
49+
["MainState"] = "server",
50+
["CurrentErrorList"] = "server",
51+
["OverallCurrentState"] = "server",
52+
["OverallTargetState"] = "server",
53+
["LatchControlModes"] = "server",
54+
["AcceptedCommandList"] = "server",
55+
["AttributeList"] = "server",
56+
}
57+
58+
ClosureControl.command_direction_map = {
59+
["Stop"] = "server",
60+
["MoveTo"] = "server",
61+
["Calibrate"] = "server",
62+
}
63+
64+
ClosureControl.FeatureMap = ClosureControl.types.Feature
65+
66+
function ClosureControl.are_features_supported(feature, feature_map)
67+
if (ClosureControl.FeatureMap.bits_are_valid(feature)) then
68+
return (feature & feature_map) == feature
69+
end
70+
return false
71+
end
72+
73+
local attribute_helper_mt = {}
74+
attribute_helper_mt.__index = function(self, key)
75+
local direction = ClosureControl.attribute_direction_map[key]
76+
if direction == nil then
77+
error(string.format("Referenced unknown attribute %s on cluster %s", key, ClosureControl.NAME))
78+
end
79+
return ClosureControl[direction].attributes[key]
80+
end
81+
ClosureControl.attributes = {}
82+
setmetatable(ClosureControl.attributes, attribute_helper_mt)
83+
84+
local command_helper_mt = {}
85+
command_helper_mt.__index = function(self, key)
86+
local direction = ClosureControl.command_direction_map[key]
87+
if direction == nil then
88+
error(string.format("Referenced unknown command %s on cluster %s", key, ClosureControl.NAME))
89+
end
90+
return ClosureControl[direction].commands[key]
91+
end
92+
ClosureControl.commands = {}
93+
setmetatable(ClosureControl.commands, command_helper_mt)
94+
95+
setmetatable(ClosureControl, {__index = cluster_base})
96+
97+
return ClosureControl
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
local cluster_base = require "st.matter.cluster_base"
2+
local data_types = require "st.matter.data_types"
3+
local TLVParser = require "st.matter.TLV.TLVParser"
4+
5+
local AcceptedCommandList = {
6+
ID = 0xFFF9,
7+
NAME = "AcceptedCommandList",
8+
base_type = require "st.matter.data_types.Array",
9+
element_type = require "st.matter.data_types.Uint32",
10+
}
11+
12+
function AcceptedCommandList:augment_type(data_type_obj)
13+
for i, v in ipairs(data_type_obj.elements) do
14+
data_type_obj.elements[i] = data_types.validate_or_build_type(v, AcceptedCommandList.element_type)
15+
end
16+
end
17+
18+
function AcceptedCommandList:new_value(...)
19+
local o = self.base_type(table.unpack({...}))
20+
21+
return o
22+
end
23+
24+
function AcceptedCommandList:read(device, endpoint_id)
25+
return cluster_base.read(
26+
device,
27+
endpoint_id,
28+
self._cluster.ID,
29+
self.ID,
30+
nil
31+
)
32+
end
33+
34+
function AcceptedCommandList:subscribe(device, endpoint_id)
35+
return cluster_base.subscribe(
36+
device,
37+
endpoint_id,
38+
self._cluster.ID,
39+
self.ID,
40+
nil
41+
)
42+
end
43+
44+
function AcceptedCommandList:set_parent_cluster(cluster)
45+
self._cluster = cluster
46+
return self
47+
end
48+
49+
function AcceptedCommandList:build_test_report_data(
50+
device,
51+
endpoint_id,
52+
value,
53+
status
54+
)
55+
local data = data_types.validate_or_build_type(value, self.base_type)
56+
57+
return cluster_base.build_test_report_data(
58+
device,
59+
endpoint_id,
60+
self._cluster.ID,
61+
self.ID,
62+
data,
63+
status
64+
)
65+
end
66+
67+
function AcceptedCommandList:deserialize(tlv_buf)
68+
local data = TLVParser.decode_tlv(tlv_buf)
69+
70+
return data
71+
end
72+
73+
setmetatable(AcceptedCommandList, {__call = AcceptedCommandList.new_value, __index = AcceptedCommandList.base_type})
74+
return AcceptedCommandList
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
local cluster_base = require "st.matter.cluster_base"
2+
local data_types = require "st.matter.data_types"
3+
local TLVParser = require "st.matter.TLV.TLVParser"
4+
5+
local AttributeList = {
6+
ID = 0xFFFB,
7+
NAME = "AttributeList",
8+
base_type = require "st.matter.data_types.Array",
9+
element_type = require "st.matter.data_types.Uint32",
10+
}
11+
12+
function AttributeList:augment_type(data_type_obj)
13+
for i, v in ipairs(data_type_obj.elements) do
14+
data_type_obj.elements[i] = data_types.validate_or_build_type(v, AttributeList.element_type)
15+
end
16+
end
17+
18+
function AttributeList:new_value(...)
19+
local o = self.base_type(table.unpack({...}))
20+
21+
return o
22+
end
23+
24+
function AttributeList:read(device, endpoint_id)
25+
return cluster_base.read(
26+
device,
27+
endpoint_id,
28+
self._cluster.ID,
29+
self.ID,
30+
nil
31+
)
32+
end
33+
34+
function AttributeList:subscribe(device, endpoint_id)
35+
return cluster_base.subscribe(
36+
device,
37+
endpoint_id,
38+
self._cluster.ID,
39+
self.ID,
40+
nil
41+
)
42+
end
43+
44+
function AttributeList:set_parent_cluster(cluster)
45+
self._cluster = cluster
46+
return self
47+
end
48+
49+
function AttributeList:build_test_report_data(
50+
device,
51+
endpoint_id,
52+
value,
53+
status
54+
)
55+
local data = data_types.validate_or_build_type(value, self.base_type)
56+
57+
return cluster_base.build_test_report_data(
58+
device,
59+
endpoint_id,
60+
self._cluster.ID,
61+
self.ID,
62+
data,
63+
status
64+
)
65+
end
66+
67+
function AttributeList:deserialize(tlv_buf)
68+
local data = TLVParser.decode_tlv(tlv_buf)
69+
70+
return data
71+
end
72+
73+
setmetatable(AttributeList, {__call = AttributeList.new_value, __index = AttributeList.base_type})
74+
return AttributeList

0 commit comments

Comments
 (0)