Skip to content

Conversation

@nickolas-deboom
Copy link
Contributor

Check all that apply

Type of Change

  • WWST Certification Request
    • If this is your first time contributing code:
      • I have reviewed the README.md file
      • I have reviewed the CODE_OF_CONDUCT.md file
      • I have signed the CLA
    • I plan on entering a WWST Certification Request or have entered a request through the WWST Certification console at developer.smartthings.com
  • Bug fix
  • New feature
  • Refactor

Checklist

  • I have performed a self-review of my code
  • I have commented my code in hard-to-understand areas
  • I have verified my changes by testing with a device or have communicated a plan for testing
  • I am adding new behavior, such as adding a sub-driver, and have added and run new unit tests to cover the new behavior

Description of Change

Summary of Completed Tests

@github-actions
Copy link

Duplicate profile check: Passed - no duplicate profiles detected.

@github-actions
Copy link

@github-actions
Copy link

github-actions bot commented Oct 28, 2025

Test Results

   71 files    467 suites   0s ⏱️
2 451 tests 2 451 ✅ 0 💤 0 ❌
4 151 runs  4 151 ✅ 0 💤 0 ❌

Results for commit aacdf01.

♻️ This comment has been updated with latest results.

@github-actions
Copy link

github-actions bot commented Oct 28, 2025

File Coverage
All files 91%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/init.lua 96%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/sub_drivers/camera/capability_handlers.lua 71%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/sub_drivers/camera/utils.lua 90%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/sub_drivers/camera/init.lua 99%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/sub_drivers/camera/attribute_handlers.lua 92%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/sub_drivers/camera/device_configuration.lua 97%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/switch_utils/fields.lua 99%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/switch_utils/device_configuration.lua 96%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/switch_utils/utils.lua 90%
/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/sub_drivers/aqara_cube/init.lua 96%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/switch_handlers/attribute_handlers.lua 83%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/switch_handlers/capability_handlers.lua 88%
/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/third_reality_mk1/init.lua 95%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/sub_drivers/eve_energy/init.lua 92%

Minimum allowed coverage is 90%

Generated by 🐒 cobertura-action against aacdf01

Copy link
Contributor

@hcarter-775 hcarter-775 left a comment

Choose a reason for hiding this comment

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

Just an initial review but I figured I'd get these thoughts out there

if child_profile then
num_floodlight_eps = num_floodlight_eps + 1
local name = string.format("%s %d", "Floodlight", num_floodlight_eps)
driver:try_create_device(
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think we should be trying to create new children every init

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's gated by CAMERA_INITIALIZED

Copy link
Contributor

Choose a reason for hiding this comment

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

why do we have this in init at all is my question then? Why not have it in do_configure if it's meant to be a one-time call

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We could definitely move it to configure. It was placed here during testing because it was easier to just delete the inventory db to clear CAMERA_INITIALIZED and get a new profile update rather than having to re-onboard.


local function info_changed(driver, device, event, args)
-- resubscribe and initialize relevant camera capabilities if a modular update has occurred
if not compare_components(device.profile.components, args.old_st_store.profile.components) then
Copy link
Contributor

Choose a reason for hiding this comment

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

not compare_components is kinda odd wording... maybe are_profiles_equal or something like that? And then we could just pass in device.profile if we wanted to be clearer with the now.

Also, this is a useful function, I might suggest moving it to switch_utils.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I updated the name to profile_changed to kind of match the pretty similar function optional_capabilities_list_changed

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I might prefer to keep this function here for now unless it's needed elsewhere at some point in which case we could move it into a shared module

@nickolas-deboom nickolas-deboom force-pushed the add-matter-camera-support branch 2 times, most recently from 66f0b0a to 31c2294 Compare November 4, 2025 20:47
},
supported_capabilities = fields.supported_capabilities,
sub_drivers = {
require("sub_drivers.aqara_cube"),
Copy link
Contributor Author

Choose a reason for hiding this comment

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

lazy loading for other subdrivers is implemented in #2525

@nickolas-deboom nickolas-deboom force-pushed the add-matter-camera-support branch from 31c2294 to 5662469 Compare November 4, 2025 20:54
end
end

local function init_ptz(device)
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The link doesn't work, that commit may have been overwritten - could you re-link?

Copy link
Contributor

Choose a reason for hiding this comment

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

Basically just saying we could do something like your changes here: 61ee699

for most/all these init functions (at least the ones where it makes sense)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure what the benefit would be?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Just cause we need to be checking for the presence of the capabilities here, not the clusters

@nickolas-deboom nickolas-deboom force-pushed the add-matter-camera-support branch from 7a82290 to 9639115 Compare November 12, 2025 16:37
This commit splits the subdriver into separate modules for device
configuration, fields, and utils.
These changes were implemented in 7a82290 but overwritten by accident
with a force-push
@@ -0,0 +1,128 @@
name: matter-camera
Copy link
Contributor

Choose a reason for hiding this comment

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

been thinking, maybe this should just be called camera?

end
if #device:get_endpoints(clusters.OccupancySensing.ID) > 0 then
table.insert(main_component_capabilities, capabilities.motionSensor.ID)
for _, device_ep in pairs(device.endpoints) do
Copy link
Contributor

Choose a reason for hiding this comment

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

we don't really have to loop through all the endpoints, right? we can gate by the device type

[clusters.OccupancySensing.ID] = false
}

if #device:get_endpoints(clusters.WebRTCTransportProvider.ID, {cluster_type = "SERVER"}) > 0 and
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd say, even without introducing new variables or anything like that, we could still put the TransportProvider one in the check below, and if it's found, do a check for the Client requester across the whole device. Therefore we're only doing one of these, and it stays in the below logic block

local microphone_component_capabilities = {}
local doorbell_component_capabilities = {}

local cluster_processed = {
Copy link
Contributor

Choose a reason for hiding this comment

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

are there going to be >1 of these clusters on a device?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Probably not but there could be

if cap.id ~= "firmwareUpdate" and cap.id ~= "refresh" then
insert_if_missing(main_component_capabilities, cap.id)
end
elseif idx == "statusLed" 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
elseif idx == "statusLed" then
elseif idx == camera_fields.profile_components.statusLed then

and the same to the others

Comment on lines +196 to +197
local zone_management_ep_ids = device:get_endpoints(clusters.ZoneManagement.ID)
if #zone_management_ep_ids > 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.

this can be assumed to exist since the capability zoneManagement is first checked.

local function init_local_media_storage(device)
if device:supports_capability(capabilities.localMediaStorage) then
local supported_attributes = {}
if camera_utils.feature_supported(device, clusters.CameraAvStreamManagement.ID, clusters.CameraAvStreamManagement.types.Feature.LOCAL_STORAGE) 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 local storage check can be removed, since localMediaStorage capability is first checked for

button_event = capabilities.button.button(string.format("pushed_%dx", press_value), {state_change = true})
end

print("COMPONENT: ", device:endpoint_to_component(ib.endpoint_id))
Copy link
Contributor

Choose a reason for hiding this comment

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

nit remove


-- Event Handlers

local CameraEventHandlers = {}
Copy link
Contributor

Choose a reason for hiding this comment

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

oops didn't even notice there were unique events before when I made the previous suggestion- maybe let's move these to their own file as well to make everything cohesive? though it's only a small bit of code, it's a bit confusing otherwise I think?

Also, do you think we should make a new folder sub_drivers.camera.camera_handlers and put the attribute, capability, and event files in there or do you think leaving them at this level is fine? starting to look a bit crowded, but it's also in a subdriver folder so idk if it matters as much. If we did, we could also make a camera_utils folder and put all the other files in there as well, which might be nice. Not sure, what do you think?

local CameraLifecycleHandlers = {}

function CameraLifecycleHandlers.device_init(driver, device)
camera_utils.update_camera_component_map(device)
Copy link
Contributor

Choose a reason for hiding this comment

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

this was my bad, but this should probably go in the if not device:get_field(camera_fields.CAMERA_INITIALIZED) block since it only needs to be done once atm

Comment on lines +33 to +57
local num_floodlight_eps = 0
local parent_child_device = false
for _, ep in ipairs(device.endpoints or {}) do
if device:supports_server_cluster(clusters.OnOff.ID, ep.endpoint_id) then
local child_profile = device_cfg.SwitchCfg.assign_profile_for_onoff_ep(device, ep.endpoint_id)
if child_profile then
num_floodlight_eps = num_floodlight_eps + 1
local name = string.format("%s %d", "Floodlight", num_floodlight_eps)
driver:try_create_device(
{
type = "EDGE_CHILD",
label = name,
profile = child_profile,
parent_device_id = device.id,
parent_assigned_child_key = string.format("%d", ep.endpoint_id),
vendor_provided_label = name
}
)
parent_child_device = true
end
end
end
if parent_child_device then
device:set_field(fields.IS_PARENT_CHILD_DEVICE, true, {persist = true})
end
Copy link
Contributor

Choose a reason for hiding this comment

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

maybe this should be made into its own DeviceConfiguration helper function? Might de-clutter this a bit more. Also, maybe we should put the helper into match_profile itself, mirroring how its done in the main driver?

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.

5 participants