Skip to content

Commit 05fa702

Browse files
committed
Change get/set_field to get/set_field_for_endpoint
Signed-off-by: Hunsup Jung <hunsup.jung@samsung.com>
1 parent c3849ad commit 05fa702

3 files changed

Lines changed: 54 additions & 38 deletions

File tree

‎drivers/SmartThings/matter-window-covering/src/init.lua‎

Lines changed: 50 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
local capabilities = require "st.capabilities"
77
local im = require "st.matter.interaction_model"
88
local clusters = require "st.matter.clusters"
9+
local device_lib = require "st.device"
910
local MatterDriver = require "st.matter.driver"
1011
local utils = require "st.utils"
1112

@@ -41,6 +42,22 @@ local TARGET_TILT_PERCENT = {
4142

4243
local TARGET_REACH_TOLERANCE = 0.5
4344

45+
local function get_field_for_endpoint(device, field, endpoint)
46+
local field_device = device
47+
if device.network_type == device_lib.NETWORK_TYPE_CHILD then
48+
field_device = device:get_parent_device()
49+
end
50+
return field_device:get_field(string.format("%s_%d", field, endpoint))
51+
end
52+
53+
local function set_field_for_endpoint(device, field, endpoint, value, additional_params)
54+
local field_device = device
55+
if device.network_type == device_lib.NETWORK_TYPE_CHILD then
56+
field_device = device:get_parent_device()
57+
end
58+
field_device:set_field(string.format("%s_%d", field, endpoint), value, additional_params)
59+
end
60+
4461
local function find_child(parent_device, ep_id)
4562
local assigned_key = parent_device:get_field(string.format("%s_%d", ASSIGNED_CHILD_KEY, ep_id)) or ep_id
4663
return parent_device:get_child_by_parent_assigned_key(string.format("%d", assigned_key))
@@ -102,22 +119,22 @@ end
102119
--- Clears the cached target percentage and cancels any associated timeout.
103120
--- @param device any a Matter device object
104121
--- @param op_fields table a table containing operational field constants used for caching target percentages and timeouts.
105-
local function clear_cached_data(device, op_fields)
106-
local current_timer = device:get_field(op_fields.TIMEOUT)
122+
local function clear_cached_data(device, op_fields, ep)
123+
local current_timer = get_field_for_endpoint(device, op_fields.TIMEOUT, ep)
107124
if current_timer then
108125
device.thread:cancel_timer(current_timer)
109126
end
110-
device:set_field(op_fields.STATE, nil)
111-
device:set_field(op_fields.TIMEOUT, nil)
127+
set_field_for_endpoint(device, op_fields.STATE, ep, nil)
128+
set_field_for_endpoint(device, op_fields.TIMEOUT, ep, nil)
112129
end
113130

114131
--- Tries to emit the idle window shade status if no target percentages are set.
115132
--- @param device any a Matter device object
116133
local function try_emit_idle_window_shade_status(device, ep)
117-
if not device:get_field(TARGET_LIFT_PERCENT.STATE) and
118-
not device:get_field(TARGET_TILT_PERCENT.STATE) then
134+
if not get_field_for_endpoint(device, TARGET_LIFT_PERCENT.STATE, ep) and
135+
not get_field_for_endpoint(device, TARGET_TILT_PERCENT.STATE, ep) then
119136
--- gets child device if one exists for this endpoint
120-
local status_device = ep and find_child(device, ep) or device
137+
local status_device = find_child(device, ep) or device
121138
status_device:emit_event(get_idle_window_shade_status(status_device))
122139
end
123140
end
@@ -126,18 +143,18 @@ end
126143
--- @param device any a Matter device object
127144
--- @param data number the target percentage to cache
128145
--- @param op_fields table a table containing operational field constants used for caching target percentages and timeouts.
129-
local function cache_data_with_timeout(device, data, op_fields)
130-
device:set_field(op_fields.STATE, data)
131-
local previous_timer = device:get_field(op_fields.TIMEOUT)
146+
local function cache_data_with_timeout(device, data, op_fields, ep)
147+
set_field_for_endpoint(device, op_fields.STATE, ep, data)
148+
local previous_timer = get_field_for_endpoint(device, op_fields.TIMEOUT, ep)
132149
if previous_timer then
133150
device.thread:cancel_timer(previous_timer)
134151
end
135152
local new_timer = device.thread:call_with_delay(op_fields.TIMEOUT_DELAY_S, function()
136-
device:set_field(op_fields.STATE, nil)
137-
device:set_field(op_fields.TIMEOUT, nil)
138-
try_emit_idle_window_shade_status(device, nil)
153+
set_field_for_endpoint(device, op_fields.STATE, ep, nil)
154+
set_field_for_endpoint(device, op_fields.TIMEOUT, ep, nil)
155+
try_emit_idle_window_shade_status(device, ep)
139156
end)
140-
device:set_field(op_fields.TIMEOUT, new_timer)
157+
set_field_for_endpoint(device, op_fields.TIMEOUT, ep, new_timer)
141158
end
142159

143160
local function is_target_value_reached(current_value, target_value)
@@ -266,15 +283,15 @@ end
266283

267284
-- capability handlers
268285
local function handle_preset(driver, device, cmd)
286+
local endpoint_id = device:component_to_endpoint(cmd.component)
269287
local preset_target_percent = device:get_latest_state(
270288
"main",
271289
capabilities.windowShadePreset.ID,
272290
capabilities.windowShadePreset.position.NAME,
273291
DEFAULT_PRESET_LEVEL
274292
)
275-
cache_data_with_timeout(device, preset_target_percent, TARGET_LIFT_PERCENT)
293+
cache_data_with_timeout(device, preset_target_percent, TARGET_LIFT_PERCENT, endpoint_id)
276294
local hundredths_lift_percent = (100 - preset_target_percent) * 100
277-
local endpoint_id = device:component_to_endpoint(cmd.component)
278295
device:send(clusters.WindowCovering.server.commands.GoToLiftPercentage(
279296
device, endpoint_id, hundredths_lift_percent
280297
))
@@ -288,10 +305,10 @@ end
288305
local function handle_close(driver, device, cmd)
289306
local endpoint_id = device:component_to_endpoint(cmd.component)
290307
if #device:get_endpoints(clusters.WindowCovering.ID, {feature_bitmap = clusters.WindowCovering.types.Feature.LIFT}) > 0 then
291-
cache_data_with_timeout(device, device.preferences.reverse and 100 or 0, TARGET_LIFT_PERCENT)
308+
cache_data_with_timeout(device, device.preferences.reverse and 100 or 0, TARGET_LIFT_PERCENT, endpoint_id)
292309
end
293310
if #device:get_endpoints(clusters.WindowCovering.ID, {feature_bitmap = clusters.WindowCovering.types.Feature.TILT}) > 0 then
294-
cache_data_with_timeout(device, device.preferences.reverse and 100 or 0, TARGET_TILT_PERCENT)
311+
cache_data_with_timeout(device, device.preferences.reverse and 100 or 0, TARGET_TILT_PERCENT, endpoint_id)
295312
end
296313
device:send(device.preferences.reverse and
297314
clusters.WindowCovering.server.commands.UpOrOpen(device, endpoint_id) or
@@ -302,10 +319,10 @@ end
302319
local function handle_open(driver, device, cmd)
303320
local endpoint_id = device:component_to_endpoint(cmd.component)
304321
if #device:get_endpoints(clusters.WindowCovering.ID, {feature_bitmap = clusters.WindowCovering.types.Feature.LIFT}) > 0 then
305-
cache_data_with_timeout(device, device.preferences.reverse and 0 or 100, TARGET_LIFT_PERCENT)
322+
cache_data_with_timeout(device, device.preferences.reverse and 0 or 100, TARGET_LIFT_PERCENT, endpoint_id)
306323
end
307324
if #device:get_endpoints(clusters.WindowCovering.ID, {feature_bitmap = clusters.WindowCovering.types.Feature.TILT}) > 0 then
308-
cache_data_with_timeout(device, device.preferences.reverse and 0 or 100, TARGET_TILT_PERCENT)
325+
cache_data_with_timeout(device, device.preferences.reverse and 0 or 100, TARGET_TILT_PERCENT, endpoint_id)
309326
end
310327
device:send(device.preferences.reverse and
311328
clusters.WindowCovering.server.commands.DownOrClose(device, endpoint_id) or
@@ -322,23 +339,24 @@ end
322339
local function handle_shade_level(driver, device, cmd)
323340
local endpoint_id = device:component_to_endpoint(cmd.component)
324341
local hundredths_lift_percentage = (100 - cmd.args.shadeLevel) * 100
325-
cache_data_with_timeout(device, cmd.args.shadeLevel, TARGET_LIFT_PERCENT)
342+
cache_data_with_timeout(device, cmd.args.shadeLevel, TARGET_LIFT_PERCENT, endpoint_id)
326343
device:send(clusters.WindowCovering.server.commands.GoToLiftPercentage(
327344
device, endpoint_id, hundredths_lift_percentage
328345
))
329346
end
330347

331348
local function handle_step_shade_level(driver, device, cmd)
349+
local endpoint_id = device:component_to_endpoint(cmd.component)
332350
local step = cmd.args.stepSize
333351
local latest_lift_percentage = device:get_latest_state(
334352
"main",
335353
capabilities.windowShadeLevel.ID,
336354
capabilities.windowShadeLevel.shadeLevel.NAME,
337355
0
338356
)
339-
local target_lift_percent = device:get_field(TARGET_LIFT_PERCENT.STATE) or latest_lift_percentage
357+
local target_lift_percent = get_field_for_endpoint(device, TARGET_LIFT_PERCENT.STATE, endpoint_id) or latest_lift_percentage
340358
local updated_target_lift = utils.clamp_value(target_lift_percent + step, 0, 100)
341-
cache_data_with_timeout(device, updated_target_lift, TARGET_LIFT_PERCENT)
359+
cache_data_with_timeout(device, updated_target_lift, TARGET_LIFT_PERCENT, endpoint_id)
342360
driver:inject_capability_command(device, {
343361
capability = capabilities.windowShadeLevel.ID,
344362
component = cmd.component,
@@ -351,7 +369,7 @@ end
351369
local function handle_shade_tilt_level(driver, device, cmd)
352370
local endpoint_id = device:component_to_endpoint(cmd.component)
353371
local hundredths_tilt_percentage = (100 - cmd.args.level) * 100
354-
cache_data_with_timeout(device, cmd.args.level, TARGET_TILT_PERCENT)
372+
cache_data_with_timeout(device, cmd.args.level, TARGET_TILT_PERCENT, endpoint_id)
355373
device:send(clusters.WindowCovering.server.commands.GoToTiltPercentage(
356374
device, endpoint_id, hundredths_tilt_percentage
357375
))
@@ -362,9 +380,8 @@ local function current_position_lift_percent_100ths_handler(driver, device, ib,
362380
if not ib.data.value then return end
363381
local lift_percent = 100 - math.floor(ib.data.value / 100)
364382
device:emit_event_for_endpoint(ib.endpoint_id, capabilities.windowShadeLevel.shadeLevel(lift_percent))
365-
366-
if is_target_value_reached(lift_percent, device:get_field(TARGET_LIFT_PERCENT.STATE)) then
367-
clear_cached_data(device, TARGET_LIFT_PERCENT)
383+
if is_target_value_reached(lift_percent, get_field_for_endpoint(device, TARGET_LIFT_PERCENT.STATE, ib.endpoint_id)) then
384+
clear_cached_data(device, TARGET_LIFT_PERCENT, ib.endpoint_id)
368385
try_emit_idle_window_shade_status(device, ib.endpoint_id)
369386
end
370387
end
@@ -373,9 +390,8 @@ local function current_position_tilt_percent_100ths_handler(driver, device, ib,
373390
if not ib.data.value then return end
374391
local tilt_percent = 100 - math.floor(ib.data.value / 100)
375392
device:emit_event_for_endpoint(ib.endpoint_id, capabilities.windowShadeTiltLevel.shadeTiltLevel(tilt_percent))
376-
377-
if is_target_value_reached(tilt_percent, device:get_field(TARGET_TILT_PERCENT.STATE)) then
378-
clear_cached_data(device, TARGET_TILT_PERCENT)
393+
if is_target_value_reached(tilt_percent, get_field_for_endpoint(device, TARGET_TILT_PERCENT.STATE, ib.endpoint_id)) then
394+
clear_cached_data(device, TARGET_TILT_PERCENT, ib.endpoint_id)
379395
try_emit_idle_window_shade_status(device, ib.endpoint_id)
380396
end
381397
end
@@ -389,10 +405,10 @@ local function target_position_lift_percent_100ths_handler(driver, device, ib, r
389405
capabilities.windowShadeLevel.shadeLevel.NAME
390406
)
391407
if latest_lift_percentage and is_target_value_reached(latest_lift_percentage, target_lift_percent) then
392-
clear_cached_data(device, TARGET_LIFT_PERCENT)
408+
clear_cached_data(device, TARGET_LIFT_PERCENT, ib.endpoint_id)
393409
try_emit_idle_window_shade_status(device, ib.endpoint_id)
394410
else
395-
cache_data_with_timeout(device, target_lift_percent, TARGET_LIFT_PERCENT)
411+
cache_data_with_timeout(device, target_lift_percent, TARGET_LIFT_PERCENT, ib.endpoint_id)
396412
end
397413
end
398414
end
@@ -406,10 +422,10 @@ local function target_position_tilt_percent_100ths_handler(driver, device, ib, r
406422
capabilities.windowShadeTiltLevel.shadeTiltLevel.NAME
407423
)
408424
if latest_tilt_percent and is_target_value_reached(latest_tilt_percent, target_tilt_percent) then
409-
clear_cached_data(device, TARGET_TILT_PERCENT)
425+
clear_cached_data(device, TARGET_TILT_PERCENT, ib.endpoint_id)
410426
try_emit_idle_window_shade_status(device, ib.endpoint_id)
411427
else
412-
cache_data_with_timeout(device, target_tilt_percent, TARGET_TILT_PERCENT)
428+
cache_data_with_timeout(device, target_tilt_percent, TARGET_TILT_PERCENT, ib.endpoint_id)
413429
end
414430
end
415431
end

‎drivers/SmartThings/matter-window-covering/src/test/test_matter_multi_window_covering.lua‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ test.register_coroutine_test(
581581
}
582582
)
583583
test.wait_for_events()
584-
assert(mock_child_device[i]:get_field("__target_lift_percent") == 50)
584+
assert(mock_parent_device:get_field(string.format("__target_lift_percent_%d", CHILD_DEVICE_MAP[i].ep)) == 50)
585585
end
586586
end,
587587
{
@@ -602,7 +602,7 @@ test.register_coroutine_test(
602602
}
603603
)
604604
test.wait_for_events()
605-
assert(mock_child_device[i]:get_field("__target_tilt_percent") == 50)
605+
assert(mock_parent_device:get_field(string.format("__target_tilt_percent_%d", CHILD_DEVICE_MAP[i].ep)) == 50)
606606
end
607607
end,
608608
{

‎drivers/SmartThings/matter-window-covering/src/test/test_matter_window_covering.lua‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ test.register_coroutine_test(
465465
}
466466
)
467467
test.wait_for_events()
468-
assert(mock_device:get_field("__target_lift_percent") == 50)
468+
assert(mock_device:get_field("__target_lift_percent_10") == 50)
469469
end,
470470
{
471471
min_api_version = 17
@@ -484,7 +484,7 @@ test.register_coroutine_test(
484484
}
485485
)
486486
test.wait_for_events()
487-
assert(mock_device:get_field("__target_tilt_percent") == 50)
487+
assert(mock_device:get_field("__target_tilt_percent_10") == 50)
488488
end,
489489
{
490490
min_api_version = 17

0 commit comments

Comments
 (0)