@@ -9,6 +9,67 @@ clusters.ClosureControl = require "embedded_clusters.ClosureControl"
99
1010local ClosureAttributeHandlers = {}
1111
12+ local function set_closure_control_state (device , endpoint_id , field )
13+ local cache = device :get_field (closure_fields .CLOSURE_CONTROL_STATE_CACHE ) or {}
14+ if not cache [endpoint_id ] then cache [endpoint_id ] = {} end
15+ for k , v in pairs (field ) do
16+ cache [endpoint_id ][k ] = v
17+ end
18+ device :set_field (closure_fields .CLOSURE_CONTROL_STATE_CACHE , cache )
19+ end
20+
21+ local function emit_closure_control_capability (device , endpoint_id )
22+ local closure_control_state = device :get_field (closure_fields .CLOSURE_CONTROL_STATE_CACHE )[endpoint_id ] or {}
23+
24+ local main = closure_control_state .main
25+ local current = closure_control_state .current
26+ local target = closure_control_state .target
27+
28+ local closure_capability = capabilities .windowShade .windowShade
29+ if device :supports_capability_by_id (capabilities .doorControl .ID ) then
30+ closure_capability = capabilities .doorControl .door
31+ end
32+
33+ if main == clusters .ClosureControl .types .MainStateEnum .MOVING then
34+ if target == clusters .ClosureControl .types .TargetPositionEnum .MOVE_TO_FULLY_CLOSED then
35+ device :emit_event_for_endpoint (endpoint_id , closure_capability .closing ())
36+ elseif target == clusters .ClosureControl .types .TargetPositionEnum .MOVE_TO_FULLY_OPEN then
37+ device :emit_event_for_endpoint (endpoint_id , closure_capability .opening ())
38+ end
39+ elseif main == clusters .ClosureControl .types .MainStateEnum .STOPPED or main == nil then
40+ if current == nil then return end
41+ if current == clusters .ClosureControl .types .CurrentPositionEnum .FULLY_CLOSED then
42+ device :emit_event_for_endpoint (endpoint_id , closure_capability .closed ())
43+ elseif current == clusters .ClosureControl .types .CurrentPositionEnum .FULLY_OPENED or
44+ device :supports_capability_by_id (capabilities .doorControl .ID ) then
45+ -- doorControl does not support partially open; treat any not- fully closed as open
46+ device :emit_event_for_endpoint (endpoint_id , closure_capability .open ())
47+ else
48+ device :emit_event_for_endpoint (endpoint_id , closure_capability .partially_open ())
49+ end
50+ end
51+ end
52+
53+ function ClosureAttributeHandlers .main_state_attr_handler (driver , device , ib , response )
54+ if ib .data .value == nil then return end
55+ set_closure_control_state (device , ib .endpoint_id , { main = ib .data .value })
56+ emit_closure_control_capability (device , ib .endpoint_id )
57+ end
58+
59+ function ClosureAttributeHandlers .overall_current_state_attr_handler (driver , device , ib , response )
60+ if ib .data .elements == nil or ib .data .elements .position == nil or ib .data .elements .position .value == nil then return end
61+ local current = ib .data .elements .position .value
62+ set_closure_control_state (device , ib .endpoint_id , { current = current })
63+ emit_closure_control_capability (device , ib .endpoint_id )
64+ end
65+
66+ function ClosureAttributeHandlers .overall_target_state_attr_handler (driver , device , ib , response )
67+ if ib .data .elements == nil or ib .data .elements .position == nil or ib .data .elements .position .value == nil then return end
68+ local target = ib .data .elements .position .value
69+ set_closure_control_state (device , ib .endpoint_id , { target = target })
70+ emit_closure_control_capability (device , ib .endpoint_id )
71+ end
72+
1273ClosureAttributeHandlers .current_pos_handler = function (attribute )
1374 return function (driver , device , ib , response )
1475 if ib .data .value == nil then return end
@@ -67,76 +128,4 @@ function ClosureAttributeHandlers.level_attr_handler(driver, device, ib, respons
67128 device :emit_event_for_endpoint (ib .endpoint_id , capabilities .windowShadeLevel .shadeLevel (level ))
68129end
69130
70- function ClosureAttributeHandlers .main_state_attr_handler (driver , device , ib , response )
71- if ib .data .value == nil then return end
72- local windowShade = capabilities .windowShade .windowShade
73- local current_state = device :get_field (closure_fields .CURRENT_STATE ) or clusters .ClosureControl .types .CurrentPositionEnum .FULLY_CLOSED
74- local target_state = device :get_field (closure_fields .TARGET_STATE ) or clusters .ClosureControl .types .TargetPositionEnum .MOVE_TO_FULLY_CLOSED
75-
76- if device :supports_capability_by_id (capabilities .windowShade .ID ) then
77- if ib .data .value == clusters .ClosureControl .types .MainStateEnum .MOVING then
78- if target_state == clusters .ClosureControl .types .TargetPositionEnum .MOVE_TO_FULLY_CLOSED then
79- device :emit_event_for_endpoint (ib .endpoint_id , windowShade .closing ())
80- elseif target_state == clusters .ClosureControl .types .TargetPositionEnum .MOVE_TO_FULLY_OPEN then
81- device :emit_event_for_endpoint (ib .endpoint_id , windowShade .opening ())
82- end
83- elseif ib .data .value == clusters .ClosureControl .types .MainStateEnum .STOPPED then
84- if current_state == clusters .ClosureControl .types .CurrentPositionEnum .FULLY_CLOSED then
85- device :emit_event_for_endpoint (ib .endpoint_id , windowShade .closed ())
86- elseif current_state == clusters .ClosureControl .types .CurrentPositionEnum .FULLY_OPENED then
87- device :emit_event_for_endpoint (ib .endpoint_id , windowShade .open ())
88- else -- PARTIALLY_OPENED, OPENED_FOR_PEDESTRIAN, OPENED_FOR_VENTILATION, or OPENED_AT_SIGNATURE
89- device :emit_event_for_endpoint (ib .endpoint_id , windowShade .partially_open ())
90- end
91- end
92- else -- device:supports_capability_by_id(capabilities.doorControl.ID)
93- if ib .data .value == clusters .ClosureControl .types .MainStateEnum .MOVING then
94- if target_state == clusters .ClosureControl .types .TargetPositionEnum .MOVE_TO_FULLY_CLOSED then
95- device :emit_event_for_endpoint (ib .endpoint_id , capabilities .doorControl .door .closing ())
96- elseif target_state == clusters .ClosureControl .types .TargetPositionEnum .MOVE_TO_FULLY_OPEN then
97- device :emit_event_for_endpoint (ib .endpoint_id , capabilities .doorControl .door .opening ())
98- end
99- elseif ib .data .value == clusters .ClosureControl .types .MainStateEnum .STOPPED then
100- if current_state == clusters .ClosureControl .types .CurrentPositionEnum .FULLY_CLOSED then
101- device :emit_event_for_endpoint (ib .endpoint_id , capabilities .doorControl .door .closed ())
102- else
103- device :emit_event_for_endpoint (ib .endpoint_id , capabilities .doorControl .doorControl .open ())
104- end
105- end
106- end
107- device :set_field (closure_fields .MAIN_STATE , ib .data .value )
108- end
109-
110- function ClosureAttributeHandlers .overall_current_state_attr_handler (driver , device , ib , response )
111- if ib .data .elements == nil or ib .data .elements .position .value == nil then return end
112- local windowShade = capabilities .windowShade .windowShade
113- local main_state = device :get_field (closure_fields .MAIN_STATE ) or clusters .ClosureControl .types .MainStateEnum .STOPPED
114-
115- if device :supports_capability_by_id (capabilities .windowShade .ID ) then
116- if main_state == clusters .ClosureControl .types .MainStateEnum .STOPPED then
117- if ib .data .elements .position .value == clusters .ClosureControl .types .CurrentPositionEnum .FULLY_CLOSED then
118- device :emit_event_for_endpoint (ib .endpoint_id , windowShade .closed ())
119- elseif ib .data .elements .position .value == clusters .ClosureControl .types .CurrentPositionEnum .FULLY_OPENED then
120- device :emit_event_for_endpoint (ib .endpoint_id , windowShade .open ())
121- else -- PARTIALLY_OPENED, OPENED_FOR_PEDESTRIAN, OPENED_FOR_VENTILATION, or OPENED_AT_SIGNATURE
122- device :emit_event_for_endpoint (ib .endpoint_id , windowShade .partially_open ())
123- end
124- end
125- else -- device:supports_capability_by_id(capabilities.doorControl.ID)
126- if main_state == clusters .ClosureControl .types .MainStateEnum .STOPPED then
127- if ib .data .elements .position .value == clusters .ClosureControl .types .CurrentPositionEnum .FULLY_CLOSED then
128- device :emit_event_for_endpoint (ib .endpoint_id , capabilities .doorControl .door .closed ())
129- else
130- device :emit_event_for_endpoint (ib .endpoint_id , capabilities .doorControl .doorControl .open ())
131- end
132- end
133- end
134- device :set_field (closure_fields .CURRENT_STATE , ib .data .elements .position .value )
135- end
136-
137- function ClosureAttributeHandlers .overall_target_state_attr_handler (driver , device , ib , response )
138- if ib .data .elements == nil or ib .data .elements .position .value == nil then return end
139- device :set_field (closure_fields .TARGET_STATE , ib .data .elements .position .value )
140- end
141-
142131return ClosureAttributeHandlers
0 commit comments