Skip to content

Commit 697c1d0

Browse files
authored
Gate Pre-58 FW logic for modular profiles (#2350)
1 parent 4de1762 commit 697c1d0

File tree

6 files changed

+81
-64
lines changed

6 files changed

+81
-64
lines changed

drivers/SmartThings/matter-sensor/src/air-quality-sensor/init.lua

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -401,13 +401,17 @@ local function match_modular_profile(driver, device)
401401

402402
device:try_update_metadata({profile = profile_name, optional_component_capabilities = optional_supported_component_capabilities})
403403

404-
-- add mandatory capabilities for subscription
405-
local total_supported_capabilities = optional_supported_component_capabilities
406-
table.insert(total_supported_capabilities[MAIN_COMPONENT_IDX][CAPABILITIES_LIST_IDX], capabilities.airQualityHealthConcern.ID)
407-
table.insert(total_supported_capabilities[MAIN_COMPONENT_IDX][CAPABILITIES_LIST_IDX], capabilities.refresh.ID)
408-
table.insert(total_supported_capabilities[MAIN_COMPONENT_IDX][CAPABILITIES_LIST_IDX], capabilities.firmwareUpdate.ID)
409-
410-
device:set_field(SUPPORTED_COMPONENT_CAPABILITIES, total_supported_capabilities, { persist = true })
404+
-- earlier modular profile gating (min api v14, rpc 8) ensures we are running >= 0.57 FW.
405+
-- This gating specifies a workaround required only for 0.57 FW, which is not needed for 0.58 and higher.
406+
if version.api < 15 or version.rpc < 9 then
407+
-- add mandatory capabilities for subscription
408+
local total_supported_capabilities = optional_supported_component_capabilities
409+
table.insert(total_supported_capabilities[MAIN_COMPONENT_IDX][CAPABILITIES_LIST_IDX], capabilities.airQualityHealthConcern.ID)
410+
table.insert(total_supported_capabilities[MAIN_COMPONENT_IDX][CAPABILITIES_LIST_IDX], capabilities.refresh.ID)
411+
table.insert(total_supported_capabilities[MAIN_COMPONENT_IDX][CAPABILITIES_LIST_IDX], capabilities.firmwareUpdate.ID)
412+
413+
device:set_field(SUPPORTED_COMPONENT_CAPABILITIES, total_supported_capabilities, { persist = true })
414+
end
411415
end
412416

413417
local function do_configure(driver, device)
@@ -436,9 +440,14 @@ end
436440

437441
local function device_init(driver, device)
438442
if device:get_field(SUPPORTED_COMPONENT_CAPABILITIES) then
439-
-- assume that device is using a modular profile, override supports_capability_by_id
440-
-- library function to utilize optional capabilities
441-
device:extend_device("supports_capability_by_id", supports_capability_by_id_modular)
443+
if version.api >= 15 and version.rpc >= 9 then
444+
-- the device used this modular profile workaround on 0.57 FW but no longer requires this table with >=0.58 FW
445+
device:set_field(SUPPORTED_COMPONENT_CAPABILITIES, nil)
446+
else
447+
-- assume that device is using a modular profile on 0.57 FW, override supports_capability_by_id
448+
-- library function to utilize optional capabilities
449+
device:extend_device("supports_capability_by_id", supports_capability_by_id_modular)
450+
end
442451
end
443452
device:subscribe()
444453
end

drivers/SmartThings/matter-thermostat/src/init.lua

Lines changed: 42 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -492,9 +492,14 @@ end
492492

493493
local function device_init(driver, device)
494494
if device:get_field(SUPPORTED_COMPONENT_CAPABILITIES) then
495-
-- assume that device is using a modular profile, override supports_capability_by_id
496-
-- library function to utilize optional capabilities
497-
device:extend_device("supports_capability_by_id", supports_capability_by_id_modular)
495+
if version.api >= 15 and version.rpc >= 9 then
496+
-- the device used this modular profile workaround on 0.57 FW but no longer requires this table with >=0.58 FW
497+
device:set_field(SUPPORTED_COMPONENT_CAPABILITIES, nil)
498+
else
499+
-- assume that device is using a modular profile on 0.57 FW, override supports_capability_by_id
500+
-- library function to utilize optional capabilities
501+
device:extend_device("supports_capability_by_id", supports_capability_by_id_modular)
502+
end
498503
end
499504
device:subscribe()
500505
device:set_component_to_endpoint_fn(component_to_endpoint)
@@ -985,14 +990,18 @@ local function match_modular_profile_air_purifer(driver, device)
985990

986991
device:try_update_metadata({profile = profile_name, optional_component_capabilities = optional_supported_component_capabilities})
987992

988-
-- add mandatory capabilities for subscription
989-
local total_supported_capabilities = optional_supported_component_capabilities
990-
table.insert(total_supported_capabilities[MAIN_COMPONENT_IDX][CAPABILITIES_LIST_IDX], capabilities.airPurifierFanMode.ID)
991-
table.insert(total_supported_capabilities[MAIN_COMPONENT_IDX][CAPABILITIES_LIST_IDX], capabilities.fanSpeedPercent.ID)
992-
table.insert(total_supported_capabilities[MAIN_COMPONENT_IDX][CAPABILITIES_LIST_IDX], capabilities.refresh.ID)
993-
table.insert(total_supported_capabilities[MAIN_COMPONENT_IDX][CAPABILITIES_LIST_IDX], capabilities.firmwareUpdate.ID)
993+
-- earlier modular profile gating (min api v14, rpc 8) ensures we are running >= 0.57 FW.
994+
-- This gating specifies a workaround required only for 0.57 FW, which is not needed for 0.58 and higher.
995+
if version.api < 15 or version.rpc < 9 then
996+
-- add mandatory capabilities for subscription
997+
local total_supported_capabilities = optional_supported_component_capabilities
998+
table.insert(total_supported_capabilities[MAIN_COMPONENT_IDX][CAPABILITIES_LIST_IDX], capabilities.airPurifierFanMode.ID)
999+
table.insert(total_supported_capabilities[MAIN_COMPONENT_IDX][CAPABILITIES_LIST_IDX], capabilities.fanSpeedPercent.ID)
1000+
table.insert(total_supported_capabilities[MAIN_COMPONENT_IDX][CAPABILITIES_LIST_IDX], capabilities.refresh.ID)
1001+
table.insert(total_supported_capabilities[MAIN_COMPONENT_IDX][CAPABILITIES_LIST_IDX], capabilities.firmwareUpdate.ID)
9941002

995-
device:set_field(SUPPORTED_COMPONENT_CAPABILITIES, total_supported_capabilities, { persist = true })
1003+
device:set_field(SUPPORTED_COMPONENT_CAPABILITIES, total_supported_capabilities, { persist = true })
1004+
end
9961005
end
9971006

9981007
local function match_modular_profile_thermostat(driver, device)
@@ -1035,14 +1044,18 @@ local function match_modular_profile_thermostat(driver, device)
10351044
table.insert(optional_supported_component_capabilities, {"main", main_component_capabilities})
10361045
device:try_update_metadata({profile = profile_name, optional_component_capabilities = optional_supported_component_capabilities})
10371046

1038-
-- add mandatory capabilities for subscription
1039-
local total_supported_capabilities = optional_supported_component_capabilities
1040-
table.insert(main_component_capabilities, capabilities.thermostatMode.ID)
1041-
table.insert(main_component_capabilities, capabilities.temperatureMeasurement.ID)
1042-
table.insert(main_component_capabilities, capabilities.refresh.ID)
1043-
table.insert(main_component_capabilities, capabilities.firmwareUpdate.ID)
1047+
-- earlier modular profile gating (min api v14, rpc 8) ensures we are running >= 0.57 FW.
1048+
-- This gating specifies a workaround required only for 0.57 FW, which is not needed for 0.58 and higher.
1049+
if version.api < 15 or version.rpc < 9 then
1050+
-- add mandatory capabilities for subscription
1051+
local total_supported_capabilities = optional_supported_component_capabilities
1052+
table.insert(main_component_capabilities, capabilities.thermostatMode.ID)
1053+
table.insert(main_component_capabilities, capabilities.temperatureMeasurement.ID)
1054+
table.insert(main_component_capabilities, capabilities.refresh.ID)
1055+
table.insert(main_component_capabilities, capabilities.firmwareUpdate.ID)
10441056

1045-
device:set_field(SUPPORTED_COMPONENT_CAPABILITIES, total_supported_capabilities, { persist = true })
1057+
device:set_field(SUPPORTED_COMPONENT_CAPABILITIES, total_supported_capabilities, { persist = true })
1058+
end
10461059
end
10471060

10481061
local function match_modular_profile_room_ac(driver, device)
@@ -1086,15 +1099,19 @@ local function match_modular_profile_room_ac(driver, device)
10861099
table.insert(optional_supported_component_capabilities, {"main", main_component_capabilities})
10871100
device:try_update_metadata({profile = profile_name, optional_component_capabilities = optional_supported_component_capabilities})
10881101

1089-
-- add mandatory capabilities for subscription
1090-
local total_supported_capabilities = optional_supported_component_capabilities
1091-
table.insert(main_component_capabilities, capabilities.switch.ID)
1092-
table.insert(main_component_capabilities, capabilities.temperatureMeasurement.ID)
1093-
table.insert(main_component_capabilities, capabilities.thermostatMode.ID)
1094-
table.insert(main_component_capabilities, capabilities.refresh.ID)
1095-
table.insert(main_component_capabilities, capabilities.firmwareUpdate.ID)
1102+
-- earlier modular profile gating (min api v14, rpc 8) ensures we are running >= 0.57 FW.
1103+
-- This gating specifies a workaround required only for 0.57 FW, which is not needed for 0.58 and higher.
1104+
if version.api < 15 or version.rpc < 9 then
1105+
-- add mandatory capabilities for subscription
1106+
local total_supported_capabilities = optional_supported_component_capabilities
1107+
table.insert(main_component_capabilities, capabilities.switch.ID)
1108+
table.insert(main_component_capabilities, capabilities.temperatureMeasurement.ID)
1109+
table.insert(main_component_capabilities, capabilities.thermostatMode.ID)
1110+
table.insert(main_component_capabilities, capabilities.refresh.ID)
1111+
table.insert(main_component_capabilities, capabilities.firmwareUpdate.ID)
10961112

1097-
device:set_field(SUPPORTED_COMPONENT_CAPABILITIES, total_supported_capabilities, { persist = true })
1113+
device:set_field(SUPPORTED_COMPONENT_CAPABILITIES, total_supported_capabilities, { persist = true })
1114+
end
10981115
end
10991116

11001117
local function match_modular_profile(driver, device, device_type)

drivers/SmartThings/matter-thermostat/src/test/test_matter_air_purifier_modular.lua

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@
1515
local test = require "integration_test"
1616
local capabilities = require "st.capabilities"
1717
local t_utils = require "integration_test.utils"
18-
local utils = require "st.utils"
19-
local dkjson = require "dkjson"
2018
local clusters = require "st.matter.clusters"
2119
local im = require "st.matter.interaction_model"
2220
local uint32 = require "st.matter.data_types.Uint32"
@@ -326,10 +324,10 @@ test.register_coroutine_test(
326324

327325
test.wait_for_events()
328326

329-
local device_info_copy = utils.deep_copy(mock_device_basic.raw_st_data)
330-
device_info_copy.profile.id = "air-purifier-modular"
331-
local device_info_json = dkjson.encode(device_info_copy)
332-
test.socket.device_lifecycle:__queue_receive({ mock_device_basic.id, "infoChanged", device_info_json })
327+
local updated_device_profile = t_utils.get_profile_definition("air-purifier-modular.yml",
328+
{enabled_optional_capabilities = expected_update_metadata.optional_component_capabilities}
329+
)
330+
test.socket.device_lifecycle:__queue_receive(mock_device_basic:generate_info_changed({ profile = updated_device_profile }))
333331
test.socket.matter:__expect_send({mock_device_basic.id, subscribe_request})
334332
end,
335333
{ test_init = test_init_basic }
@@ -400,10 +398,10 @@ test.register_coroutine_test(
400398

401399
test.wait_for_events()
402400

403-
local device_info_copy = utils.deep_copy(mock_device_ap_thermo_aqs.raw_st_data)
404-
device_info_copy.profile.id = "air-purifier-modular"
405-
local device_info_json = dkjson.encode(device_info_copy)
406-
test.socket.device_lifecycle:__queue_receive({ mock_device_ap_thermo_aqs.id, "infoChanged", device_info_json })
401+
local updated_device_profile = t_utils.get_profile_definition("air-purifier-modular.yml",
402+
{enabled_optional_capabilities = expected_update_metadata.optional_component_capabilities}
403+
)
404+
test.socket.device_lifecycle:__queue_receive(mock_device_ap_thermo_aqs:generate_info_changed({ profile = updated_device_profile }))
407405
test.socket.matter:__expect_send({mock_device_ap_thermo_aqs.id, subscribe_request})
408406
end,
409407
{ test_init = test_init_ap_thermo_aqs_preconfigured }

drivers/SmartThings/matter-thermostat/src/test/test_matter_room_ac_modular.lua

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,6 @@
1414
local test = require "integration_test"
1515
local capabilities = require "st.capabilities"
1616
local t_utils = require "integration_test.utils"
17-
local utils = require "st.utils"
18-
local dkjson = require "dkjson"
1917
local clusters = require "st.matter.clusters"
2018
local im = require "st.matter.interaction_model"
2119
local uint32 = require "st.matter.data_types.Uint32"
@@ -291,11 +289,10 @@ local function test_room_ac_device_type_update_modular_profile(generic_mock_devi
291289
clusters.Thermostat.attributes.AttributeList:build_test_report_data(generic_mock_device, 1, {thermostat_attr_list_value})
292290
})
293291
generic_mock_device:expect_metadata_update(expected_metadata)
294-
295-
local device_info_copy = utils.deep_copy(generic_mock_device.raw_st_data)
296-
device_info_copy.profile.id = "room-air-conditioner-modular"
297-
local device_info_json = dkjson.encode(device_info_copy)
298-
test.socket.device_lifecycle:__queue_receive({ generic_mock_device.id, "infoChanged", device_info_json })
292+
local updated_device_profile = t_utils.get_profile_definition("air-purifier-modular.yml",
293+
{enabled_optional_capabilities = expected_metadata.optional_component_capabilities}
294+
)
295+
test.socket.device_lifecycle:__queue_receive(generic_mock_device:generate_info_changed({ profile = updated_device_profile }))
299296
test.socket.matter:__expect_send({generic_mock_device.id, subscribe_request})
300297
end
301298

drivers/SmartThings/matter-thermostat/src/test/test_matter_thermo_multiple_device_types.lua

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@
1515
local test = require "integration_test"
1616
local t_utils = require "integration_test.utils"
1717
local clusters = require "st.matter.clusters"
18-
local dkjson = require "dkjson"
1918
local uint32 = require "st.matter.data_types.Uint32"
20-
local utils = require "st.utils"
2119

2220
local mock_device = test.mock_device.build_test_matter_device({
2321
profile = t_utils.get_profile_definition("thermostat-humidity-fan.yml"),
@@ -196,10 +194,10 @@ local function test_thermostat_device_type_update_modular_profile(generic_mock_d
196194

197195
test.wait_for_events()
198196

199-
local device_info_copy = utils.deep_copy(generic_mock_device.raw_st_data)
200-
device_info_copy.profile.id = "thermostat-modular"
201-
local device_info_json = dkjson.encode(device_info_copy)
202-
test.socket.device_lifecycle:__queue_receive({ generic_mock_device.id, "infoChanged", device_info_json })
197+
local updated_device_profile = t_utils.get_profile_definition("thermostat-modular.yml",
198+
{enabled_optional_capabilities = expected_metadata.optional_component_capabilities}
199+
)
200+
test.socket.device_lifecycle:__queue_receive(generic_mock_device:generate_info_changed({ profile = updated_device_profile }))
203201
test.socket.matter:__expect_send({generic_mock_device.id, subscribe_request})
204202
end
205203

drivers/SmartThings/matter-thermostat/src/test/test_matter_thermostat_modular.lua

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,8 @@
1515
local test = require "integration_test"
1616
local t_utils = require "integration_test.utils"
1717
local clusters = require "st.matter.clusters"
18-
local dkjson = require "dkjson"
1918
local im = require "st.matter.interaction_model"
2019
local uint32 = require "st.matter.data_types.Uint32"
21-
local utils = require "st.utils"
2220

2321
test.disable_startup_messages()
2422

@@ -122,10 +120,10 @@ local function test_thermostat_device_type_update_modular_profile(generic_mock_d
122120
})
123121
generic_mock_device:expect_metadata_update(expected_metadata)
124122

125-
local device_info_copy = utils.deep_copy(generic_mock_device.raw_st_data)
126-
device_info_copy.profile.id = "thermostat-modular"
127-
local device_info_json = dkjson.encode(device_info_copy)
128-
test.socket.device_lifecycle:__queue_receive({ generic_mock_device.id, "infoChanged", device_info_json })
123+
local updated_device_profile = t_utils.get_profile_definition("thermostat-modular.yml",
124+
{enabled_optional_capabilities = expected_metadata.optional_component_capabilities}
125+
)
126+
test.socket.device_lifecycle:__queue_receive(mock_device_basic:generate_info_changed({ profile = updated_device_profile }))
129127
test.socket.matter:__expect_send({generic_mock_device.id, subscribe_request})
130128
end
131129

0 commit comments

Comments
 (0)