Skip to content

Matter Switch: Add greater Energy profiling logic for Switches #2199

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
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
@@ -1,24 +1,24 @@
name: light-level-power-energy-powerConsumption
components:
- id: main
capabilities:
- id: switch
version: 1
- id: switchLevel
version: 1
config:
values:
- key: "level.value"
range: [1, 100]
- id: powerMeter
version: 1
- id: energyMeter
version: 1
- id: powerConsumptionReport
version: 1
- id: firmwareUpdate
version: 1
- id: refresh
version: 1
categories:
- name: Light
- id: main
capabilities:
- id: switch
version: 1
- id: switchLevel
version: 1
config:
values:
- key: "level.value"
range: [1, 100]
- id: powerMeter
version: 1
- id: energyMeter
version: 1
- id: powerConsumptionReport
version: 1
- id: firmwareUpdate
version: 1
- id: refresh
version: 1
categories:
- name: Light
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
name: light-power-energy-powerConsumption
components:
- id: main
capabilities:
- id: switch
version: 1
- id: powerMeter
version: 1
- id: energyMeter
version: 1
- id: powerConsumptionReport
version: 1
- id: firmwareUpdate
version: 1
- id: refresh
version: 1
categories:
- name: Light
- id: main
capabilities:
- id: switch
version: 1
- id: powerMeter
version: 1
- id: energyMeter
version: 1
- id: powerConsumptionReport
version: 1
- id: firmwareUpdate
version: 1
- id: refresh
version: 1
categories:
- name: Light
337 changes: 220 additions & 117 deletions drivers/SmartThings/matter-switch/src/init.lua

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ local function test_init()
end

test.socket.matter:__expect_send({aqara_mock_device.id, subscribe_request})
aqara_mock_device:set_field("__ELECTRICAL_TOPOLOGY", {topology = false, tags_on_ep = {}}, {persist = false}) -- since we're assuming this would have happened during device_added in this case.
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})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ local aqara_mock_device = test.mock_device.build_test_matter_device({
clusters = {
{cluster_id = clusters.Basic.ID, cluster_type = "SERVER"},
{cluster_id = clusters.ElectricalPowerMeasurement.ID, cluster_type = "SERVER", cluster_revision = 1, feature_map = 2 },
{cluster_id = clusters.ElectricalEnergyMeasurement.ID, cluster_type = "SERVER", cluster_revision = 1, feature_map = 5 }
{cluster_id = clusters.ElectricalEnergyMeasurement.ID, cluster_type = "SERVER", cluster_revision = 1, feature_map = 5 },
{cluster_id = clusters.PowerTopology.ID, cluster_type = "SERVER", cluster_revision = 1, feature_map = 1 } -- NODE_TOPOLOGY
},
device_types = {
{device_type_id = 0x0016, device_type_revision = 1}, -- RootNode
Expand Down Expand Up @@ -177,10 +178,12 @@ local function test_init()
end
end
test.socket.matter:__expect_send({aqara_mock_device.id, subscribe_request})

-- Test added -> doConfigure logic
test.socket.device_lifecycle:__queue_receive({ aqara_mock_device.id, "added" })
test.socket.matter:__expect_send({aqara_mock_device.id, subscribe_request})
test.socket.device_lifecycle:__queue_receive({ aqara_mock_device.id, "doConfigure" })
test.mock_devices_api._expected_device_updates[aqara_mock_device.device_id] = "00000000-1111-2222-3333-000000000001"
test.mock_devices_api._expected_device_updates[1] = {device_id = "00000000-1111-2222-3333-000000000001"}
test.mock_devices_api._expected_device_updates[1].metadata = {deviceId="00000000-1111-2222-3333-000000000001", profileReference="4-button"}
aqara_mock_device:expect_metadata_update({ profile = "4-button" })
aqara_mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" })
test.mock_device.add_test_device(aqara_mock_device)
-- to test powerConsumptionReport
Expand Down Expand Up @@ -277,7 +280,7 @@ test.register_coroutine_test(
{
-- don't use "aqara_mock_children[aqara_child1_ep].id,"
-- because energy management is at the root endpoint.
aqara_mock_device.id,
aqara_mock_children[aqara_child1_ep].id,
clusters.ElectricalPowerMeasurement.attributes.ActivePower:build_test_report_data(aqara_mock_device, 1, 17000)
}
)
Expand All @@ -289,7 +292,7 @@ test.register_coroutine_test(

test.socket.matter:__queue_receive(
{
aqara_mock_device.id,
aqara_mock_children[aqara_child1_ep].id,
clusters.ElectricalEnergyMeasurement.attributes.CumulativeEnergyImported:build_test_report_data(aqara_mock_device, 1, cumulative_report_val_19)
}
)
Expand All @@ -302,7 +305,7 @@ test.register_coroutine_test(
-- This is because related variable settings are required in set_poll_report_timer_and_schedule().
test.socket.matter:__queue_receive(
{
aqara_mock_device.id,
aqara_mock_children[aqara_child1_ep].id,
clusters.ElectricalEnergyMeasurement.attributes.CumulativeEnergyImported:build_test_report_data(aqara_mock_device, 1, cumulative_report_val_29)
}
)
Expand All @@ -313,10 +316,8 @@ test.register_coroutine_test(

test.socket.matter:__queue_receive(
{
aqara_mock_device.id,
clusters.ElectricalEnergyMeasurement.attributes.CumulativeEnergyImported:build_test_report_data(
aqara_mock_device, 1, cumulative_report_val_39
)
aqara_mock_children[aqara_child1_ep].id,
clusters.ElectricalEnergyMeasurement.attributes.CumulativeEnergyImported:build_test_report_data(aqara_mock_device, 1, cumulative_report_val_39)
}
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
local test = require "integration_test"
local capabilities = require "st.capabilities"
local t_utils = require "integration_test.utils"
local uint32 = require "st.matter.data_types.Uint32"

local clusters = require "st.matter.clusters"

Expand Down Expand Up @@ -42,6 +43,7 @@ local mock_device = test.mock_device.build_test_matter_device({
clusters = {
{ cluster_id = clusters.ElectricalEnergyMeasurement.ID, cluster_type = "SERVER", feature_map = 14, },
{ cluster_id = clusters.ElectricalPowerMeasurement.ID, cluster_type = "SERVER", feature_map = 0, },
{ cluster_id = clusters.PowerTopology.ID, cluster_type = "SERVER", feature_map = 4, }, -- SET_TOPOLOGY
},
device_types = {
{ device_type_id = 0x0510, device_type_revision = 1 }, -- Electrical Sensor
Expand All @@ -51,10 +53,30 @@ local mock_device = test.mock_device.build_test_matter_device({
endpoint_id = 2,
clusters = {
{ cluster_id = clusters.OnOff.ID, cluster_type = "SERVER", cluster_revision = 1, feature_map = 0, },
{cluster_id = clusters.LevelControl.ID, cluster_type = "SERVER", feature_map = 2}
{ cluster_id = clusters.LevelControl.ID, cluster_type = "SERVER", feature_map = 2},
},
device_types = {
{ device_type_id = 0x010A, device_type_revision = 1 } -- OnOff Plug
{ device_type_id = 0x010B, device_type_revision = 1 }, -- OnOff Dimmable Plug
}
},
{
endpoint_id = 3,
clusters = {
{ cluster_id = clusters.ElectricalEnergyMeasurement.ID, cluster_type = "SERVER", feature_map = 14, },
{ cluster_id = clusters.PowerTopology.ID, cluster_type = "SERVER", feature_map = 4, }, -- SET_TOPOLOGY
},
device_types = {
{ device_type_id = 0x0510, device_type_revision = 1 }, -- Electrical Sensor
}
},
{
endpoint_id = 4,
clusters = {
{ cluster_id = clusters.OnOff.ID, cluster_type = "SERVER", cluster_revision = 1, feature_map = 0, },
{ cluster_id = clusters.LevelControl.ID, cluster_type = "SERVER", feature_map = 2},
},
device_types = {
{ device_type_id = 0x010B, device_type_revision = 1 }, -- OnOff Dimmable Plug
}
},
},
Expand All @@ -80,16 +102,20 @@ local mock_device_periodic = test.mock_device.build_test_matter_device({
{
endpoint_id = 1,
clusters = {
{ cluster_id = clusters.OnOff.ID, cluster_type = "SERVER", cluster_revision = 1, feature_map = 0, },
{ cluster_id = clusters.ElectricalEnergyMeasurement.ID, cluster_type = "SERVER", feature_map = 10, },
{ cluster_id = clusters.PowerTopology.ID, cluster_type = "SERVER", feature_map = 4, } -- SET_TOPOLOGY
},
device_types = {
{ device_type_id = 0x0510, device_type_revision = 1 } -- Electrical Sensor
{ device_type_id = 0x010A, device_type_revision = 1 }, -- OnOff Plug
{ device_type_id = 0x0510, device_type_revision = 1 }, -- Electrical Sensor
}
},
},
})

local subscribed_attributes_periodic = {
clusters.OnOff.attributes.OnOff,
clusters.ElectricalEnergyMeasurement.attributes.PeriodicEnergyImported,
clusters.ElectricalEnergyMeasurement.attributes.CumulativeEnergyImported,
}
Expand Down Expand Up @@ -643,19 +669,52 @@ test.register_coroutine_test(
test.register_coroutine_test(
"Test profile change on init for Electrical Sensor device type",
function()
test.socket.device_lifecycle:__queue_receive({ mock_device.id, "added" })
local read_req = clusters.PowerTopology.attributes.AvailableEndpoints:read(mock_device.id, 1)
read_req:merge(clusters.PowerTopology.attributes.AvailableEndpoints:read(mock_device.id, 3))
test.socket.matter:__expect_send({ mock_device.id, read_req })
local subscribe_request = subscribed_attributes[1]:subscribe(mock_device)
for i, cluster in ipairs(subscribed_attributes) do
if i > 1 then
subscribe_request:merge(cluster:subscribe(mock_device))
end
end
test.socket.matter:__expect_send({ mock_device.id, subscribe_request })
test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" })
mock_device:expect_metadata_update({ profile = "plug-level-power-energy-powerConsumption" })
mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" })
test.wait_for_events()
test.socket.matter:__queue_receive({ mock_device.id, clusters.PowerTopology.attributes.AvailableEndpoints:build_test_report_data(mock_device, 1, {uint32(2)})})
test.socket.matter:__queue_receive({ mock_device.id, clusters.PowerTopology.attributes.AvailableEndpoints:build_test_report_data(mock_device, 3, {uint32(4)})})
mock_device:expect_metadata_update({ profile = "plug-level-power-energy-powerConsumption" })
mock_device:expect_device_create({
type = "EDGE_CHILD",
label = "nil 2",
profile = "plug-level-energy-powerConsumption",
parent_device_id = mock_device.id,
parent_assigned_child_key = string.format("%d", 4)
})
end,
{ test_init = test_init }
)

test.register_coroutine_test(
"Test profile change on init for only Periodic Electrical Sensor device type",
function()
test.socket.device_lifecycle:__queue_receive({ mock_device_periodic.id, "added" })
local read_req = clusters.PowerTopology.attributes.AvailableEndpoints:read(mock_device_periodic.id, 1)
test.socket.matter:__expect_send({ mock_device_periodic.id, read_req })
local subscribe_request = subscribed_attributes_periodic[1]:subscribe(mock_device_periodic)
for i, cluster in ipairs(subscribed_attributes_periodic) do
if i > 1 then
subscribe_request:merge(cluster:subscribe(mock_device_periodic))
end
end
test.socket.matter:__expect_send({ mock_device_periodic.id, subscribe_request })
test.socket.device_lifecycle:__queue_receive({ mock_device_periodic.id, "doConfigure" })
mock_device_periodic:expect_metadata_update({ profile = "plug-energy-powerConsumption" })
mock_device_periodic:expect_metadata_update({ provisioning_state = "PROVISIONED" })
test.wait_for_events()
test.socket.matter:__queue_receive({ mock_device_periodic.id, clusters.PowerTopology.attributes.AvailableEndpoints:build_test_report_data(mock_device_periodic, 1, {uint32(1)})})
mock_device_periodic:expect_metadata_update({ profile = "plug-energy-powerConsumption" })
end,
{ test_init = test_init_periodic }
)
Expand Down Expand Up @@ -692,7 +751,7 @@ test.register_message_test(
direction = "receive",
message = {
mock_device.id,
clusters.LevelControl.server.commands.MoveToLevelWithOnOff:build_test_command_response(mock_device, 2)
clusters.LevelControl.server.commands.MoveToLevelWithOnOff:build_test_command_response(mock_device, 1)
}
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ local function test_init()
if i > 1 then subscribe_request:merge(clus:subscribe(mock_device)) end
end
test.socket.matter:__expect_send({mock_device.id, subscribe_request})
mock_device:set_field("__ELECTRICAL_TOPOLOGY", {topology = false, tags_on_ep = {}}, {persist = false}) -- since we're assuming this would have happened during device_added in this case.
test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" })
mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" })
test.mock_device.add_test_device(mock_device)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ local function test_init()
end
test.socket.matter:__expect_send({mock_device.id, subscribe_request})
test.mock_device.add_test_device(mock_device)
mock_device:set_field("__ELECTRICAL_TOPOLOGY", {topology = false, tags_on_ep = {}}, {persist = false}) -- since we're assuming this would have happened during device_added in this case.
test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" })
mock_device:expect_metadata_update({ profile = "light-color-level-fan" })
mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ local function test_init()
if i > 1 then subscribe_request:merge(clus:subscribe(mock_device)) end
end
test.socket.matter:__expect_send({mock_device.id, subscribe_request})
mock_device:set_field("__ELECTRICAL_TOPOLOGY", {topology = false, tags_on_ep = {}}, {persist = false}) -- since we're assuming this would have happened during device_added in this case.
test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" })
mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" })
test.mock_device.add_test_device(mock_device)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ local function test_init()
if i > 1 then subscribe_request:merge(clus:subscribe(mock_device)) end
end
test.socket.matter:__expect_send({mock_device.id, subscribe_request})
mock_device:set_field("__ELECTRICAL_TOPOLOGY", {topology = false, tags_on_ep = {}}, {persist = false}) -- since we're assuming this would have happened during device_added in this case.
test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" })
mock_device:expect_metadata_update({ profile = "light-level-3-button" })
mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" })
Expand Down Expand Up @@ -236,6 +237,7 @@ local function test_init_mcd_unsupported_switch_device_type()
end
end
test.socket.matter:__expect_send({mock_device_mcd_unsupported_switch_device_type.id, subscribe_request})
mock_device_mcd_unsupported_switch_device_type:set_field("__ELECTRICAL_TOPOLOGY", {topology = false, tags_on_ep = {}}, {persist = false}) -- since we're assuming this would have happened during device_added in this case.
test.socket.device_lifecycle:__queue_receive({ mock_device_mcd_unsupported_switch_device_type.id, "doConfigure" })
mock_device_mcd_unsupported_switch_device_type:expect_metadata_update({ profile = "2-button" })
mock_device_mcd_unsupported_switch_device_type:expect_metadata_update({ provisioning_state = "PROVISIONED" })
Expand Down
Loading
Loading