Skip to content

Conversation

@nickolas-deboom
Copy link
Contributor

This implements a few changes to the way that devices supporting batteries are profiled:

  • subscribe to PowerSource.AttributeList rather than reading this attribute, to help prevent failed reads from causing issues with device profiling
  • update the profile within match_profile rather than power_source_attribute_list_handler
  • use existing structure for handling waiting for profiling data before attempting a profile update

This implements a few changes to the way that devices supporting
batteries are profiled:
* subscribe to PowerSource.AttributeList rather than reading this
  attribute, to help prevent failed reads from causing issues with
  device profiling
* update the profile within match_profile rather than
  power_source_attribute_list_handler
* use existing structure for handling waiting for profiling data before
  attempting a profile update
@github-actions
Copy link

device:add_subscribed_attribute(clusters.PowerSource.attributes.AttributeList)
else
device:set_field(fields.profiling_data.BATTERY_SUPPORT, fields.battery_support.NO_BATTERY, {persist = true})
end
Copy link
Contributor Author

@nickolas-deboom nickolas-deboom Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is needed because the device may fingerprint to a profile excluding battery, so PowerSource.AttributeList wouldn't be included in the initial subscription and the profile update would never occur. Let me know if you have thoughts on the placement of this block. I thought it made sense to put in added since it's only needed once.

@github-actions
Copy link

github-actions bot commented Jan 21, 2026

Test Results

   71 files    480 suites   0s ⏱️
2 490 tests 2 490 ✅ 0 💤 0 ❌
4 274 runs  4 274 ✅ 0 💤 0 ❌

Results for commit ac6e8e6.

♻️ This comment has been updated with latest results.

@github-actions
Copy link

github-actions bot commented Jan 21, 2026

File Coverage
All files 92%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/sub_drivers/camera/camera_utils/device_configuration.lua 97%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/sub_drivers/camera/camera_utils/utils.lua 96%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/sub_drivers/ikea_scroll/init.lua 85%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/switch_utils/embedded_cluster_utils.lua 38%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/switch_utils/device_configuration.lua 97%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/switch_utils/utils.lua 91%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/switch_handlers/capability_handlers.lua 89%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/switch_handlers/attribute_handlers.lua 85%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/switch_handlers/event_handlers.lua 97%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/sub_drivers/aqara_cube/init.lua 96%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/sub_drivers/eve_energy/init.lua 91%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/sub_drivers/camera/init.lua 97%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/sub_drivers/camera/camera_handlers/attribute_handlers.lua 95%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/sub_drivers/camera/camera_handlers/capability_handlers.lua 78%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/init.lua 97%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/sub_drivers/third_reality_mk1/init.lua 95%

Minimum allowed coverage is 90%

Generated by 🐒 cobertura-action against ac6e8e6

)})
expect_configure_buttons()
mock_device:expect_metadata_update({ profile = "button-battery" })
end
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This logic does not work very well within test_init, because the test framework does not seem to guarantee the timing of the PROVISIONED update unless the profile update occurs within doConfigure. Since it's being handled later in this case, it only seems to work in an external function like this, which is why I converted all the test cases to the register_coroutine_test format.

end
if switch_utils.get_product_override_field(device, "is_climate_sensor_w100") then
profile_name = "3-button-battery-temperature-humidity"
end
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It turns out that this is the only unique handling needed for this device (plus the existing logic in find_default_endpoint), so I was able to remove the extra block in power_source_attribute_list_handler


-- 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
if #device:get_endpoints(clusters.PowerSource.ID, {feature_bitmap = clusters.PowerSource.types.PowerSourceFeature.BATTERY}) > 0 then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if #device:get_endpoints(clusters.PowerSource.ID, {feature_bitmap = clusters.PowerSource.types.PowerSourceFeature.BATTERY}) > 0 then
if device:get_field(fields.profiling_data.BATTERY_SUPPORT) == nil then

Does this make sense? Subscribe to the AttributeList if BATTERY_SUPPORT has not yet been handled?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But what if the device doesn't support PowerSource?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current logic you have set up sets NO_BATTERY for all devices, whether or not they have power source?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh my b I see what you meant. Yeah I think what you suggested should work fine

Copy link
Contributor Author

@nickolas-deboom nickolas-deboom Jan 21, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I think it's better as-is because otherwise, existing devices that don't support batteries would have this field unset at driver init and therefore would subscribe to the AttributeList

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I think I still prefer this option because what it means is that we'll only actually subscribe to this attribute as long as we need to. As in, once the attribute is actually handled, this logic would have us no longer subscribe to that, keeping the subscription more lean as we've previously tried to maintain.

To keep this behavior, I have 2 thoughts.

  1. Should do that field setting in init?
  2. All that would mean is that these devices with unset fields will now subscribe once, and set the field, then go back to being unsubscribed. I'm not sure this is that bad?


-- 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
if #device:get_endpoints(clusters.PowerSource.ID, {feature_bitmap = clusters.PowerSource.types.PowerSourceFeature.BATTERY}) > 0 then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current logic you have set up sets NO_BATTERY for all devices, whether or not they have power source?

@nickolas-deboom nickolas-deboom force-pushed the matter-switch-improve-battery-profiling branch from 48c5b71 to ac6e8e6 Compare January 21, 2026 21:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants