Skip to content

Isolate the eve-energy subdriver to private cluster usage#3019

Open
samadDotDev wants to merge 3 commits into
mainfrom
fix/eve-energy-overindexing
Open

Isolate the eve-energy subdriver to private cluster usage#3019
samadDotDev wants to merge 3 commits into
mainfrom
fix/eve-energy-overindexing

Conversation

@samadDotDev

@samadDotDev samadDotDev commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Type of Change

  • Bug fix

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

The eve-energy sub-driver was being loaded even for other Eve devices that don't contain the private cluster (which eve energy subdriver uses for energy/power measurements pre-1.3). This change limits the scope of that subdriver to just the devices that contains such private cluster (id of which has the encoding for Eve's vendor id already) AND when device doesn't have the standard device type that was later introduced in Matter.

Summary of Completed Tests

  • Added unit tests (these are AI-generated)
  • Tested with Eve Energy (containing standard + private clusters)
  • Tested with another Eve device that uses matter-switch driver but doesn't contain electrical sensor or that private cluster

@samadDotDev samadDotDev added AIReview CGAI Contains code that was generated by AI labels Jun 8, 2026
@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown

@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown

Test Results

   73 files    515 suites   0s ⏱️
2 906 tests 2 906 ✅ 0 💤 0 ❌
4 802 runs  4 802 ✅ 0 💤 0 ❌

Results for commit d141a47.

♻️ This comment has been updated with latest results.

@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown

File Coverage
All files 92%
/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/aqara_cube/init.lua 95%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/sub_drivers/ikea_scroll/init.lua 87%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/switch_handlers/capability_handlers.lua 92%
/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/switch_handlers/attribute_handlers.lua 80%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/sub_drivers/camera/camera_handlers/attribute_handlers.lua 96%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/sub_drivers/camera/camera_handlers/capability_handlers.lua 84%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/sub_drivers/camera/camera_utils/device_configuration.lua 94%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/sub_drivers/camera/camera_utils/utils.lua 98%
/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 92%
/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/third_reality_mk1/init.lua 95%
/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/ikea_scroll/scroll_handlers/event_handlers.lua 93%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/matter-switch/src/sub_drivers/camera/init.lua 96%

Minimum allowed coverage is 90%

Generated by 🐒 cobertura-action against d141a47

Comment thread drivers/SmartThings/matter-switch/src/test/test_eve_energy.lua Outdated
Comment on lines +205 to +215
test.register_coroutine_test(
"Eve Energy sub-driver can_handle should return false for devices with Electrical Sensor device type",
function()
local eve_energy_can_handle = require("sub_drivers.eve_energy.can_handle")
local result = eve_energy_can_handle(nil, nil, mock_eve_device_using_electrical_sensor)
assert(result == false, "can_handle should return false for Eve device with electrical sensor")
end,
{
min_api_version = 17
}
)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this is already tested in this file

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah this is indirectly tested by a larger test but I wanted to add specific tests for can_handle in all 3 combinations (with private cluster, electrical sensor device type, and both). I can remove this one though.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed in 5d2a4d2

Comment on lines +18 to +39
-- Helper function to add get_endpoints method to mock devices for can_handle testing
local function add_get_endpoints_to_mock(device)
device.get_endpoints = function(self, cluster_id, opts)
opts = opts or {}
local eps = {}
for _, ep in ipairs(self.endpoints) do
for _, cluster in ipairs(ep.clusters or {}) do
if cluster.cluster_id == cluster_id then
-- Check feature_bitmap if specified
if opts.feature_bitmap == nil or
(cluster.feature_map and (cluster.feature_map & opts.feature_bitmap) == opts.feature_bitmap) then
table.insert(eps, ep.endpoint_id)
break
end
end
end
end
return eps
end
return device
end

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this feels like an overcomplicated solution. I might suggest we just add one more mock device with both clusters present.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I actually started with that i.e. by adding this util function to can_handle and that'd just work best for mock device in tests, but didn't want to influence the functional code just because of test infra not providing device::get_endpoints:

diff --git a/drivers/SmartThings/matter-switch/src/sub_drivers/eve_energy/can_handle.lua b/drivers/SmartThings/matter-switch/s
rc/sub_drivers/eve_energy/can_handle.lua
index 02bc9e06..b5b536a4 100644
--- a/drivers/SmartThings/matter-switch/src/sub_drivers/eve_energy/can_handle.lua
+++ b/drivers/SmartThings/matter-switch/src/sub_drivers/eve_energy/can_handle.lua
@@ -5,13 +5,24 @@ local device_lib = require "st.device"
 local fields = require "switch_utils.fields"
 local switch_utils = require "switch_utils.utils"

+local function has_cluster(device, cluster_id)
+  for _, ep in ipairs(device.endpoints) do
+    for _, cluster in ipairs(ep.clusters or {}) do
+      if cluster.cluster_id == cluster_id then
+        return true
+      end
+    end
+  end
+  return false
+end
+
 return function(opts, driver, device)
   local EVE_PRIVATE_CLUSTER_ID = 0x130AFC01
   -- this sub driver loads for devices that:
   -- 1. Contain the Eve Private Cluster (0x130AFC01)
   -- 2. Do NOT have the Standard Electrical Sensor device type
   if device.network_type == device_lib.NETWORK_TYPE_MATTER and
-    #device:get_endpoints(EVE_PRIVATE_CLUSTER_ID) > 0 and
+    has_cluster(device, EVE_PRIVATE_CLUSTER_ID) and
     #switch_utils.get_endpoints_by_device_type(device, fields.DEVICE_TYPE_ID.ELECTRICAL_SENSOR) == 0 then
     return true, require("sub_drivers.eve_energy")
   end

Let me know what you prefer, and curious about thoughts from @ctowns as well here!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I made that change in 5d2a4d2 but LMK if you were thinking something different.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Ah, I see the issue you're mentioning. Not to spend too much more time on this, but perhaps it would be better to implicitly test can_handle by just adding an init test instead of an explicit can_handle test? It is a little annoying that the current infrastructure doesn't well support direct can_handle tests, so this is more or less the way that other drivers do it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

If you have issues with that, I do think it would be better to revert to the first version you made than to affect the actual can_handle code.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Yeah at that point we're exercising what existing tests are already doing implicitly and seems odd to cover all cases of specifically can_handle. I have reverted the change in d141a47

local PRIVATE_ATTR_ID_ACCUMULATED_CONTROL_POINT = 0x130A000E

-- Helper function to add get_endpoints method to mock devices
local function add_get_endpoints_to_mock(device)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Just a note: technically this does not match the lua library definition of the get_endpoints function, but I think it covers the test appropriately. The alternative would be to manually register each of the new mock devices using their own test init function so that the device function metatable is populated with functions like get_endpoints from the lua libs, but I think that is too much overhead for just doing a quick can_handle test for each of these mock devices, and this works well for the purposes of this test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AIReview CGAI Contains code that was generated by AI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants