Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -342,29 +342,29 @@ function AttributeHandlers.bat_charge_level_handler(driver, device, ib, response
end

function AttributeHandlers.power_source_attribute_list_handler(driver, device, ib, response)
local profile_name = ""

local profile_name
local button_eps = device:get_endpoints(clusters.Switch.ID, {feature_bitmap=clusters.Switch.types.SwitchFeature.MOMENTARY_SWITCH})
for _, attr in ipairs(ib.data.elements) do
-- Re-profile the device if BatPercentRemaining (Attribute ID 0x0C) or
-- BatChargeLevel (Attribute ID 0x0E) is present.
if attr.value == 0x0C then
-- Re-profile the device if BatPercentRemaining or BatChargeLevel is present, exiting
-- the loop early if BatPercentRemaining is found to prefer button-battery profile.
if attr.value == clusters.PowerSource.attributes.BatPercentRemaining.ID then
profile_name = "button-battery"
break
elseif attr.value == 0x0E then
elseif attr.value == clusters.PowerSource.attributes.BatChargeLevel.ID then
profile_name = "button-batteryLevel"
break
end
end
if profile_name ~= "" then
if profile_name then
if #button_eps > 1 then
profile_name = string.format("%d-", #button_eps) .. profile_name
end

if switch_utils.get_product_override_field(device, "is_climate_sensor_w100") then
profile_name = profile_name .. "-temperature-humidity"
end
device:try_update_metadata({ profile = profile_name })
if profile_name ~= device:get_field(fields.BUTTON_PROFILE_NAME) then
device:try_update_metadata({ profile = profile_name })
device:set_field(fields.BUTTON_PROFILE_NAME, profile_name, {persist = true})
end
end
end

Expand Down
6 changes: 6 additions & 0 deletions drivers/SmartThings/matter-switch/src/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,12 @@ function SwitchLifecycleHandlers.device_init(driver, device)
end
end
end
-- For devices supporting BATTERY, add the PowerSource AttributeList to the list of subscribed
-- attributes in order to determine whether to use the battery or batteryLevel capability.
local battery_supported = #device:get_endpoints(clusters.PowerSource.ID, {feature_bitmap = clusters.PowerSource.types.PowerSourceFeature.BATTERY}) > 0
if battery_supported then
device:add_subscribed_attribute(clusters.PowerSource.attributes.AttributeList)
end
device:subscribe()

-- device energy reporting must be handled cumulatively, periodically, or by both simulatanously.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ local function test_init()
test.disable_startup_messages()
test.mock_device.add_test_device(aqara_mock_device)
local cluster_subscribe_list = {
clusters.PowerSource.server.attributes.AttributeList,
clusters.PowerSource.server.attributes.BatPercentRemaining,
clusters.TemperatureMeasurement.attributes.MeasuredValue,
clusters.TemperatureMeasurement.attributes.MinMeasuredValue,
Expand All @@ -148,8 +149,6 @@ local function test_init()
test.socket.matter:__expect_send({aqara_mock_device.id, subscribe_request})

test.socket.device_lifecycle:__queue_receive({ aqara_mock_device.id, "doConfigure" })
local read_attribute_list = clusters.PowerSource.attributes.AttributeList:read()
test.socket.matter:__expect_send({aqara_mock_device.id, read_attribute_list})
configure_buttons()
aqara_mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" })

Expand Down
24 changes: 20 additions & 4 deletions drivers/SmartThings/matter-switch/src/test/test_matter_button.lua
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ local mock_device = test.mock_device.build_test_matter_device({

-- add device for each mock device
local CLUSTER_SUBSCRIBE_LIST ={
clusters.PowerSource.server.attributes.AttributeList,
clusters.PowerSource.server.attributes.BatPercentRemaining,
clusters.Switch.server.events.InitialPress,
clusters.Switch.server.events.LongPress,
Expand Down Expand Up @@ -72,8 +73,6 @@ local function test_init()

test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" })
mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" })
local read_attribute_list = clusters.PowerSource.attributes.AttributeList:read()
test.socket.matter:__expect_send({mock_device.id, read_attribute_list})
configure_buttons()

local device_info_copy = utils.deep_copy(mock_device.raw_st_data)
Expand Down Expand Up @@ -387,15 +386,32 @@ test.register_coroutine_test(
test.socket.matter:__queue_receive(
{
mock_device.id,
clusters.PowerSource.attributes.AttributeList:build_test_report_data(mock_device, 1, {uint32(12)})
clusters.PowerSource.attributes.AttributeList:build_test_report_data(mock_device, 1, {uint32(
clusters.PowerSource.attributes.BatPercentRemaining.ID
)})
}
)
mock_device:expect_metadata_update({ profile = "button-battery" })
end
)

test.register_coroutine_test(
"Test profile does not change to button-battery when battery percent remaining attribute (attribute ID 12) is not available",
"Test profile change to button-batteryLevel when battery percent remaining attribute (attribute ID 14) is available",
function()
test.socket.matter:__queue_receive(
{
mock_device.id,
clusters.PowerSource.attributes.AttributeList:build_test_report_data(mock_device, 1, {uint32(
clusters.PowerSource.attributes.BatChargeLevel.ID
)})
}
)
mock_device:expect_metadata_update({ profile = "button-batteryLevel" })
end
)

test.register_coroutine_test(
"Test profile does not update when battery attributes are not available",
function()
test.socket.matter:__queue_receive(
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ local mock_device = test.mock_device.build_test_matter_device(

-- add device for each mock device
local CLUSTER_SUBSCRIBE_LIST ={
clusters.PowerSource.server.attributes.AttributeList,
clusters.PowerSource.server.attributes.BatPercentRemaining,
clusters.Switch.server.events.InitialPress,
clusters.Switch.server.events.LongPress,
Expand Down Expand Up @@ -136,7 +137,6 @@ local function test_init()
test.socket.device_lifecycle:__queue_receive({ mock_device.id, "init" })

--doConfigure sets the provisioning state to provisioned
test.socket.matter:__expect_send({mock_device.id, clusters.PowerSource.attributes.AttributeList:read()})
mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" })
expect_configure_buttons()
test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,7 @@ function ButtonDeviceConfiguration.update_button_profile(device, default_endpoin
profile_name = profile_name .. "-motion"
end
local battery_supported = #device:get_endpoints(clusters.PowerSource.ID, {feature_bitmap = clusters.PowerSource.types.PowerSourceFeature.BATTERY}) > 0
if battery_supported then -- battery profiles are configured later, in power_source_attribute_list_handler
device:send(clusters.PowerSource.attributes.AttributeList:read(device))
else
if not battery_supported then -- battery profiles are configured later, in power_source_attribute_list_handler
device:try_update_metadata({profile = profile_name})
end
end
Expand Down
2 changes: 2 additions & 0 deletions drivers/SmartThings/matter-switch/src/utils/switch_fields.lua
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,8 @@ SwitchFields.EMULATE_HELD = "__emulate_held" -- for non-MSR (MomentarySwitchRele
SwitchFields.SUPPORTS_MULTI_PRESS = "__multi_button" -- for MSM devices (MomentarySwitchMultiPress), create an event on receipt of MultiPressComplete
SwitchFields.INITIAL_PRESS_ONLY = "__initial_press_only" -- for devices that support MS (MomentarySwitch), but not MSR (MomentarySwitchRelease)

SwitchFields.BUTTON_PROFILE_NAME = "__button_profile_name"

SwitchFields.TEMP_BOUND_RECEIVED = "__temp_bound_received"
SwitchFields.TEMP_MIN = "__temp_min"
SwitchFields.TEMP_MAX = "__temp_max"
Expand Down
Loading