From e1f566992dbc29aa9868fdaf74ce504c807260d5 Mon Sep 17 00:00:00 2001 From: cjswedes Date: Tue, 10 Dec 2024 09:21:26 -0600 Subject: [PATCH 1/6] Remove health check from zigbee thermostat This is not needed to keep device online, and so its being removed to gain the small memory/latency savings of having it disabled. Tested with a Sinope thermostat --- drivers/SmartThings/zigbee-thermostat/src/init.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/SmartThings/zigbee-thermostat/src/init.lua b/drivers/SmartThings/zigbee-thermostat/src/init.lua index 416f9e32a7..0a5e82350e 100644 --- a/drivers/SmartThings/zigbee-thermostat/src/init.lua +++ b/drivers/SmartThings/zigbee-thermostat/src/init.lua @@ -376,6 +376,7 @@ local zigbee_thermostat_driver = { require("resideo_korea"), require("aqara") }, + health_check = false, } defaults.register_for_default_handlers(zigbee_thermostat_driver, zigbee_thermostat_driver.supported_capabilities) From 48b546d8f57e4c097a9eaeca4ed67dbf09efda15 Mon Sep 17 00:00:00 2001 From: cjswedes Date: Mon, 28 Oct 2024 23:54:55 -0500 Subject: [PATCH 2/6] Update zigbee tests for native handler support Hub FW 0.55.x adds support for colorTemperature and colorControl commands to native handlers. And the lua libs are registering for default for those commands for Zigbee/matter devices. --- .../src/test/test_all_capability_zigbee_bulb.lua | 2 ++ .../zigbee-switch/src/test/test_aqara_led_bulb.lua | 1 + .../SmartThings/zigbee-switch/src/test/test_aqara_light.lua | 1 + drivers/SmartThings/zigbee-switch/src/test/test_rgb_bulb.lua | 3 +++ .../SmartThings/zigbee-switch/src/test/test_rgbw_bulb.lua | 5 ++++- .../zigbee-switch/src/test/test_zll_rgbw_bulb.lua | 3 +++ 6 files changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/SmartThings/zigbee-switch/src/test/test_all_capability_zigbee_bulb.lua b/drivers/SmartThings/zigbee-switch/src/test/test_all_capability_zigbee_bulb.lua index 71f1efb426..81d355d889 100644 --- a/drivers/SmartThings/zigbee-switch/src/test/test_all_capability_zigbee_bulb.lua +++ b/drivers/SmartThings/zigbee-switch/src/test/test_all_capability_zigbee_bulb.lua @@ -348,6 +348,7 @@ test.register_coroutine_test( function() test.timer.__create_and_queue_test_time_advance_timer(2, "oneshot") test.socket.capability:__queue_receive({mock_device.id, { capability = "colorControl", component = "main", command = "setColor", args = { { hue = 50, saturation = 50 } } } }) + mock_device:expect_native_cmd_handler_registration("colorControl", "setColor") test.socket.zigbee:__expect_send( { mock_device.id, @@ -382,6 +383,7 @@ test.register_coroutine_test( function() test.socket.zigbee:__set_channel_ordering("relaxed") test.socket.capability:__queue_receive({mock_device.id, { capability = "colorTemperature", component = "main", command = "setColorTemperature", args = {1800}}}) + mock_device:expect_native_cmd_handler_registration("colorTemperature", "setColorTemperature") test.socket.zigbee:__expect_send({mock_device.id, ColorControl.server.commands.MoveToColorTemperature(mock_device, 556, 0x0000)}) test.socket.zigbee:__expect_send({mock_device.id, OnOff.server.commands.On(mock_device)}) test.wait_for_events() diff --git a/drivers/SmartThings/zigbee-switch/src/test/test_aqara_led_bulb.lua b/drivers/SmartThings/zigbee-switch/src/test/test_aqara_led_bulb.lua index 45bc9f3242..9c7a7cc0e5 100644 --- a/drivers/SmartThings/zigbee-switch/src/test/test_aqara_led_bulb.lua +++ b/drivers/SmartThings/zigbee-switch/src/test/test_aqara_led_bulb.lua @@ -123,6 +123,7 @@ test.register_coroutine_test( test.socket.capability:__queue_receive({ mock_device.id, { capability = "colorTemperature", component = "main", command = "setColorTemperature", args = { 200 } } }) + mock_device:expect_native_cmd_handler_registration("colorTemperature", "setColorTemperature") local temp_in_mired = math.floor(1000000 / 200) test.socket.zigbee:__expect_send( { diff --git a/drivers/SmartThings/zigbee-switch/src/test/test_aqara_light.lua b/drivers/SmartThings/zigbee-switch/src/test/test_aqara_light.lua index 6bd83a7afa..68f54c986f 100644 --- a/drivers/SmartThings/zigbee-switch/src/test/test_aqara_light.lua +++ b/drivers/SmartThings/zigbee-switch/src/test/test_aqara_light.lua @@ -128,6 +128,7 @@ test.register_coroutine_test( test.socket.capability:__queue_receive({ mock_device.id, { capability = "colorTemperature", component = "main", command = "setColorTemperature", args = { 200 } } }) + mock_device:expect_native_cmd_handler_registration("colorTemperature", "setColorTemperature") local temp_in_mired = math.floor(1000000 / 200) test.socket.zigbee:__expect_send( { diff --git a/drivers/SmartThings/zigbee-switch/src/test/test_rgb_bulb.lua b/drivers/SmartThings/zigbee-switch/src/test/test_rgb_bulb.lua index 2aa6dece8f..5f7e37f5eb 100644 --- a/drivers/SmartThings/zigbee-switch/src/test/test_rgb_bulb.lua +++ b/drivers/SmartThings/zigbee-switch/src/test/test_rgb_bulb.lua @@ -131,6 +131,7 @@ test.register_coroutine_test( test.timer.__create_and_queue_test_time_advance_timer(2, "oneshot") test.socket.capability:__queue_receive({mock_device.id, { capability = "colorControl", component = "main", command = "setHue", args = { 50 } } }) + mock_device:expect_native_cmd_handler_registration("colorControl", "setHue") test.socket.zigbee:__expect_send({ mock_device.id, OnOff.commands.On(mock_device) }) local hue = math.floor((50 * 0xFE) / 100.0 + 0.5) @@ -154,6 +155,7 @@ test.register_coroutine_test( test.timer.__create_and_queue_test_time_advance_timer(2, "oneshot") test.socket.capability:__queue_receive({mock_device.id, { capability = "colorControl", component = "main", command = "setSaturation", args = { 50 } } }) + mock_device:expect_native_cmd_handler_registration("colorControl", "setSaturation") test.socket.zigbee:__expect_send({ mock_device.id, OnOff.commands.On(mock_device) }) local saturation = math.floor((50 * 0xFE) / 100.0 + 0.5) @@ -176,6 +178,7 @@ test.register_coroutine_test( function() test.timer.__create_and_queue_test_time_advance_timer(2, "oneshot") test.socket.capability:__queue_receive({mock_device.id, { capability = "colorControl", component = "main", command = "setColor", args = { { hue = 50, saturation = 50 } } } }) + mock_device:expect_native_cmd_handler_registration("colorControl", "setColor") test.socket.zigbee:__expect_send( { mock_device.id, diff --git a/drivers/SmartThings/zigbee-switch/src/test/test_rgbw_bulb.lua b/drivers/SmartThings/zigbee-switch/src/test/test_rgbw_bulb.lua index 32e8956250..61a9fcf1ac 100644 --- a/drivers/SmartThings/zigbee-switch/src/test/test_rgbw_bulb.lua +++ b/drivers/SmartThings/zigbee-switch/src/test/test_rgbw_bulb.lua @@ -162,6 +162,7 @@ test.register_coroutine_test( test.timer.__create_and_queue_test_time_advance_timer(2, "oneshot") test.socket.capability:__queue_receive({mock_device.id, { capability = "colorControl", component = "main", command = "setHue", args = { 50 } } }) + mock_device:expect_native_cmd_handler_registration("colorControl", "setHue") test.socket.zigbee:__expect_send({ mock_device.id, OnOff.commands.On(mock_device) }) local hue = math.floor((50 * 0xFE) / 100.0 + 0.5) @@ -185,6 +186,7 @@ test.register_coroutine_test( test.timer.__create_and_queue_test_time_advance_timer(2, "oneshot") test.socket.capability:__queue_receive({mock_device.id, { capability = "colorControl", component = "main", command = "setSaturation", args = { 50 } } }) + mock_device:expect_native_cmd_handler_registration("colorControl", "setSaturation") test.socket.zigbee:__expect_send({ mock_device.id, OnOff.commands.On(mock_device) }) local saturation = math.floor((50 * 0xFE) / 100.0 + 0.5) @@ -208,6 +210,7 @@ test.register_coroutine_test( test.timer.__create_and_queue_test_time_advance_timer(2, "oneshot") test.socket.capability:__queue_receive({mock_device.id, { capability = "colorControl", component = "main", command = "setColor", args = { { hue = 50, saturation = 50 } } } }) + mock_device:expect_native_cmd_handler_registration("colorControl", "setColor") test.socket.zigbee:__expect_send({ mock_device.id, OnOff.server.commands.On(mock_device) }) local hue = math.floor((50 * 0xFE) / 100.0 + 0.5) @@ -228,7 +231,7 @@ test.register_coroutine_test( ) test.register_coroutine_test( - "Set Saturation command test", + "Set ColorTemperature command test", function() test.timer.__create_and_queue_test_time_advance_timer(1, "oneshot") test.socket.capability:__queue_receive({mock_device.id, { capability = "colorTemperature", component = "main", command = "setColorTemperature", args = { 200 } } }) diff --git a/drivers/SmartThings/zigbee-switch/src/test/test_zll_rgbw_bulb.lua b/drivers/SmartThings/zigbee-switch/src/test/test_zll_rgbw_bulb.lua index f2d8c5f2f4..a7aaaf5e82 100644 --- a/drivers/SmartThings/zigbee-switch/src/test/test_zll_rgbw_bulb.lua +++ b/drivers/SmartThings/zigbee-switch/src/test/test_zll_rgbw_bulb.lua @@ -197,6 +197,7 @@ test.register_coroutine_test( test.timer.__create_and_queue_test_time_advance_timer(2, "oneshot") test.socket.capability:__queue_receive({mock_device.id, { capability = "colorControl", component = "main", command = "setHue", args = { 50 } } }) + mock_device:expect_native_cmd_handler_registration("colorControl", "setHue") test.socket.zigbee:__expect_send({ mock_device.id, OnOff.commands.On(mock_device) }) local hue = math.floor((50 * 0xFE) / 100.0 + 0.5) @@ -221,6 +222,7 @@ test.register_coroutine_test( test.timer.__create_and_queue_test_time_advance_timer(2, "oneshot") test.socket.capability:__queue_receive({mock_device.id, { capability = "colorControl", component = "main", command = "setSaturation", args = { 50 } } }) + mock_device:expect_native_cmd_handler_registration("colorControl", "setSaturation") test.socket.zigbee:__expect_send({ mock_device.id, OnOff.commands.On(mock_device) }) local saturation = math.floor((50 * 0xFE) / 100.0 + 0.5) @@ -245,6 +247,7 @@ test.register_coroutine_test( test.timer.__create_and_queue_test_time_advance_timer(2, "oneshot") test.socket.capability:__queue_receive({mock_device.id, { capability = "colorControl", component = "main", command = "setColor", args = { { hue = 50, saturation = 50 } } } }) + mock_device:expect_native_cmd_handler_registration("colorControl", "setColor") test.socket.zigbee:__expect_send({ mock_device.id, OnOff.server.commands.On(mock_device) }) local hue = math.floor((50 * 0xFE) / 100.0 + 0.5) From 76c796dc64f95f175c9ba1b8737c639234775663 Mon Sep 17 00:00:00 2001 From: cjswedes Date: Wed, 11 Dec 2024 09:47:09 -0600 Subject: [PATCH 3/6] Update tests that were only passing because of a bug in the test framework There was a bug in the integration test framework that wasn't properly validating native handler registration api calls at the end of a test. --- .../test_matter_multi_button_switch_mcd.lua | 8 ----- .../test/test_fibaro_walli_double_switch.lua | 4 --- .../src/test/test_zooz_double_plug.lua | 32 ------------------- 3 files changed, 44 deletions(-) diff --git a/drivers/SmartThings/matter-switch/src/test/test_matter_multi_button_switch_mcd.lua b/drivers/SmartThings/matter-switch/src/test/test_matter_multi_button_switch_mcd.lua index a5f2420557..bf6eefee2b 100644 --- a/drivers/SmartThings/matter-switch/src/test/test_matter_multi_button_switch_mcd.lua +++ b/drivers/SmartThings/matter-switch/src/test/test_matter_multi_button_switch_mcd.lua @@ -256,14 +256,6 @@ test.register_message_test( { capability = "switch", component = "main", command = "on", args = { } } } }, - { - channel = "devices", - direction = "send", - message = { - "register_native_capability_cmd_handler", - { device_uuid = mock_device.id, capability_id = "switch", capability_cmd_id = "on" } - } - }, { channel = "matter", direction = "send", diff --git a/drivers/SmartThings/zwave-switch/src/test/test_fibaro_walli_double_switch.lua b/drivers/SmartThings/zwave-switch/src/test/test_fibaro_walli_double_switch.lua index 40d45eb200..11746559a5 100644 --- a/drivers/SmartThings/zwave-switch/src/test/test_fibaro_walli_double_switch.lua +++ b/drivers/SmartThings/zwave-switch/src/test/test_fibaro_walli_double_switch.lua @@ -437,7 +437,6 @@ test.register_coroutine_test( mock_parent.id, { capability = "switch", component = "main", command = "on", args = {} } }) - mock_parent:expect_native_cmd_handler_registration("switch", "on") test.socket.zwave:__expect_send( zw_test_utils.zwave_test_build_send_command( @@ -505,7 +504,6 @@ test.register_coroutine_test( mock_parent.id, { capability = "switch", component = "main", command = "off", args = {} } }) - mock_parent:expect_native_cmd_handler_registration("switch", "off") test.socket.zwave:__expect_send( zw_test_utils.zwave_test_build_send_command( @@ -572,7 +570,6 @@ test.register_coroutine_test( mock_child.id, { capability = "switch", component = "main", command = "on", args = {} } }) - mock_child:expect_native_cmd_handler_registration("switch", "on") test.socket.zwave:__expect_send( zw_test_utils.zwave_test_build_send_command( @@ -637,7 +634,6 @@ test.register_coroutine_test( mock_child.id, { capability = "switch", component = "main", command = "off", args = {} } }) - mock_child:expect_native_cmd_handler_registration("switch", "off") test.socket.zwave:__expect_send( zw_test_utils.zwave_test_build_send_command( diff --git a/drivers/SmartThings/zwave-switch/src/test/test_zooz_double_plug.lua b/drivers/SmartThings/zwave-switch/src/test/test_zooz_double_plug.lua index bc5c4e94a1..9f7f7d5b86 100644 --- a/drivers/SmartThings/zwave-switch/src/test/test_zooz_double_plug.lua +++ b/drivers/SmartThings/zwave-switch/src/test/test_zooz_double_plug.lua @@ -191,14 +191,6 @@ test.register_message_test( { capability = "switch", command = "on", component = "switch1", args = {} } } }, - { - channel = "devices", - direction = "send", - message = { - "register_native_capability_cmd_handler", - { device_uuid = mock_parent.id, capability_id = "switch", capability_cmd_id = "on" } - } - }, { channel = "zwave", direction = "send", @@ -223,14 +215,6 @@ test.register_message_test( { capability = "switch", command = "off", component = "main", args = {} } } }, - { - channel = "devices", - direction = "send", - message = { - "register_native_capability_cmd_handler", - { device_uuid = mock_parent.id, capability_id = "switch", capability_cmd_id = "off" } - } - }, { channel = "zwave", direction = "send", @@ -256,14 +240,6 @@ test.register_message_test( { capability = "switch", command = "on", component = "switch1", args = {} } } }, - { - channel = "devices", - direction = "send", - message = { - "register_native_capability_cmd_handler", - { device_uuid = mock_child.id, capability_id = "switch", capability_cmd_id = "on" } - } - }, { channel = "zwave", direction = "send", @@ -288,14 +264,6 @@ test.register_message_test( { capability = "switch", command = "off", component = "main", args = {} } } }, - { - channel = "devices", - direction = "send", - message = { - "register_native_capability_cmd_handler", - { device_uuid = mock_child.id, capability_id = "switch", capability_cmd_id = "off" } - } - }, { channel = "zwave", direction = "send", From 20e48727c6f00eaed2352d3da4422643b73af0c6 Mon Sep 17 00:00:00 2001 From: cjswedes Date: Wed, 11 Dec 2024 10:07:40 -0600 Subject: [PATCH 4/6] Fix matter profile switch test Its not clear if this fix is the correct fix or not. --- .../matter-switch/src/test/test_matter_switch_device_types.lua | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/SmartThings/matter-switch/src/test/test_matter_switch_device_types.lua b/drivers/SmartThings/matter-switch/src/test/test_matter_switch_device_types.lua index 4329cbce65..d896607284 100644 --- a/drivers/SmartThings/matter-switch/src/test/test_matter_switch_device_types.lua +++ b/drivers/SmartThings/matter-switch/src/test/test_matter_switch_device_types.lua @@ -345,7 +345,9 @@ end local function test_init_water_valve() test.mock_device.add_test_device(mock_device_water_valve) + test.socket.device_lifecycle:__queue_receive({ mock_device_water_valve.id, "doConfigure" }) mock_device_water_valve:expect_metadata_update({ profile = "water-valve-level" }) + mock_device_water_valve:expect_metadata_update({ provisioning_state = "PROVISIONED" }) end local function test_init_parent_child_different_types() @@ -394,6 +396,7 @@ local function test_init_parent_child_unsupported_device_type() }) end + test.register_coroutine_test( "Test profile change on init for onoff parent cluster as server", function() From 0a70f5cdcedca479236eb1fb43c91cc4cc3c25d6 Mon Sep 17 00:00:00 2001 From: Alissa Dornbos <79465613+lelandblue@users.noreply.github.com> Date: Thu, 12 Dec 2024 08:58:46 -0500 Subject: [PATCH 5/6] New Device (Matter Sensor + Matter Switch) Neo (#1815) * new-device-neo-motion * Adding door sensor * Adding power plug fingerprint --- drivers/SmartThings/matter-sensor/fingerprints.yml | 11 +++++++++++ drivers/SmartThings/matter-switch/fingerprints.yml | 6 ++++++ 2 files changed, 17 insertions(+) diff --git a/drivers/SmartThings/matter-sensor/fingerprints.yml b/drivers/SmartThings/matter-sensor/fingerprints.yml index 7e4a3ae4b6..b9d323a5f6 100644 --- a/drivers/SmartThings/matter-sensor/fingerprints.yml +++ b/drivers/SmartThings/matter-sensor/fingerprints.yml @@ -69,6 +69,17 @@ matterManufacturer: vendorId: 0x1021 productId: 0x0001 deviceProfileName: motion-contact-battery + # Neo + - id: "4991/1122" + deviceLabel: Door Sensor + vendorId: 0x137F + productId: 0x0462 + deviceProfileName: contact-battery + - id: "4991/1123" + deviceLabel: Motion Sensor + vendorId: 0x137F + productId: 0x0463 + deviceProfileName: motion-battery #Tuo - id: "5150/3" deviceLabel: "TUO Temperature Sensor" diff --git a/drivers/SmartThings/matter-switch/fingerprints.yml b/drivers/SmartThings/matter-switch/fingerprints.yml index 5b6343c34e..fffbfeb671 100644 --- a/drivers/SmartThings/matter-switch/fingerprints.yml +++ b/drivers/SmartThings/matter-switch/fingerprints.yml @@ -417,6 +417,12 @@ matterManufacturer: vendorId: 0x115A productId: 0x004B deviceProfileName: light-color-level-2700K-6500K +#Neo + - id: "4991/635" + deviceLabel: Power Plug + vendorId: 0x137F + productId: 0x027B + deviceProfileName: plug-binary #SONOFF - id: "SONOFF MINIR4M" deviceLabel: Smart Plug-in Unit From b2fa5b42e7e5a58c40994682911a2fdaab8232e3 Mon Sep 17 00:00:00 2001 From: Harrison Carter <137556605+hcarter-775@users.noreply.github.com> Date: Tue, 17 Dec 2024 10:52:22 -0600 Subject: [PATCH 6/6] create a new profile. add test case. organize test file (#1821) --- .../profiles/aqs-temp-humidity-tvoc-meas.yml | 18 ++ .../src/air-quality-sensor/init.lua | 1 + .../test/test_matter_air_quality_sensor.lua | 286 ++++++++---------- 3 files changed, 149 insertions(+), 156 deletions(-) create mode 100644 drivers/SmartThings/matter-sensor/profiles/aqs-temp-humidity-tvoc-meas.yml diff --git a/drivers/SmartThings/matter-sensor/profiles/aqs-temp-humidity-tvoc-meas.yml b/drivers/SmartThings/matter-sensor/profiles/aqs-temp-humidity-tvoc-meas.yml new file mode 100644 index 0000000000..8195eb159c --- /dev/null +++ b/drivers/SmartThings/matter-sensor/profiles/aqs-temp-humidity-tvoc-meas.yml @@ -0,0 +1,18 @@ +name: aqs-temp-humidity-tvoc-meas +components: + - id: main + capabilities: + - id: airQualityHealthConcern + version: 1 + - id: temperatureMeasurement + version: 1 + - id: relativeHumidityMeasurement + version: 1 + - id: tvocMeasurement + version: 1 + - id: firmwareUpdate + version: 1 + - id: refresh + version: 1 + categories: + - name: AirQualityDetector diff --git a/drivers/SmartThings/matter-sensor/src/air-quality-sensor/init.lua b/drivers/SmartThings/matter-sensor/src/air-quality-sensor/init.lua index 134f00a839..2b4560fe0a 100644 --- a/drivers/SmartThings/matter-sensor/src/air-quality-sensor/init.lua +++ b/drivers/SmartThings/matter-sensor/src/air-quality-sensor/init.lua @@ -162,6 +162,7 @@ local supported_profiles = "aqs-temp-humidity-all-meas", "aqs-temp-humidity-co2-pm25-tvoc-meas", "aqs-temp-humidity-tvoc-level-pm25-meas", + "aqs-temp-humidity-tvoc-meas", } local AIR_QUALITY_MAP = { diff --git a/drivers/SmartThings/matter-sensor/src/test/test_matter_air_quality_sensor.lua b/drivers/SmartThings/matter-sensor/src/test/test_matter_air_quality_sensor.lua index c23ddffb31..f2dd259d7d 100644 --- a/drivers/SmartThings/matter-sensor/src/test/test_matter_air_quality_sensor.lua +++ b/drivers/SmartThings/matter-sensor/src/test/test_matter_air_quality_sensor.lua @@ -200,6 +200,53 @@ local mock_device_co2 = test.mock_device.build_test_matter_device({ } }) +local mock_device_tvoc = test.mock_device.build_test_matter_device({ + profile = t_utils.get_profile_definition("aqs-temp-humidity-tvoc-meas.yml"), + manufacturer_info = { + vendor_id = 0x0000, + product_id = 0x0000, + }, + endpoints = { + { + endpoint_id = 0, + clusters = { + {cluster_id = clusters.Basic.ID, cluster_type = "SERVER"}, + }, + device_types = { + {device_type_id = 0x0016, device_type_revision = 1} -- RootNode + } + }, + { + endpoint_id = 1, + clusters = { + {cluster_id = clusters.AirQuality.ID, cluster_type = "SERVER"}, + {cluster_id = clusters.TemperatureMeasurement.ID, cluster_type = "SERVER"}, + {cluster_id = clusters.RelativeHumidityMeasurement.ID, cluster_type = "SERVER"}, + {cluster_id = clusters.TotalVolatileOrganicCompoundsConcentrationMeasurement.ID, cluster_type = "SERVER", feature_map = 1}, + }, + device_types = { + {device_type_id = 0x002C, device_type_revision = 1} -- Air Quality Sensor + } + } + } +}) + +-- create test_init functions +local function initialize_mock_device(generic_mock_device, generic_subscribed_attributes) + local subscribe_request = nil + for _, attributes in pairs(generic_subscribed_attributes) do + for _, attribute in ipairs(attributes) do + if subscribe_request == nil then + subscribe_request = attribute:subscribe(generic_mock_device) + else + subscribe_request:merge(attribute:subscribe(generic_mock_device)) + end + end + end + test.socket.matter:__expect_send({generic_mock_device.id, subscribe_request}) + test.mock_device.add_test_device(generic_mock_device) +end + local function test_init() local subscribed_attributes = { [capabilities.relativeHumidityMeasurement.ID] = { @@ -282,19 +329,7 @@ local function test_init() clusters.TotalVolatileOrganicCompoundsConcentrationMeasurement.attributes.LevelValue, }, } - local subscribe_request = nil - for _, attributes in pairs(subscribed_attributes) do - for _, attribute in ipairs(attributes) do - if subscribe_request == nil then - subscribe_request = attribute:subscribe(mock_device) - else - subscribe_request:merge(attribute:subscribe(mock_device)) - end - end - end - - test.socket.matter:__expect_send({mock_device.id, subscribe_request}) - test.mock_device.add_test_device(mock_device) + initialize_mock_device(mock_device, subscribed_attributes) end test.set_test_init_function(test_init) @@ -324,19 +359,7 @@ local function test_init_common() clusters.TotalVolatileOrganicCompoundsConcentrationMeasurement.attributes.MeasurementUnit, }, } - local subscribe_request = nil - for _, attributes in pairs(subscribed_attributes) do - for _, attribute in ipairs(attributes) do - if subscribe_request == nil then - subscribe_request = attribute:subscribe(mock_device_common) - else - subscribe_request:merge(attribute:subscribe(mock_device_common)) - end - end - end - - test.socket.matter:__expect_send({mock_device_common.id, subscribe_request}) - test.mock_device.add_test_device(mock_device_common) + initialize_mock_device(mock_device_common, subscribed_attributes) end local function test_init_level() @@ -383,19 +406,28 @@ local function test_init_level() clusters.TotalVolatileOrganicCompoundsConcentrationMeasurement.attributes.LevelValue, } } - local subscribe_request = nil - for _, attributes in pairs(subscribed_attributes) do - for _, attribute in ipairs(attributes) do - if subscribe_request == nil then - subscribe_request = attribute:subscribe(mock_device_level) - else - subscribe_request:merge(attribute:subscribe(mock_device_level)) - end - end - end + initialize_mock_device(mock_device_level, subscribed_attributes) +end - test.socket.matter:__expect_send({mock_device_level.id, subscribe_request}) - test.mock_device.add_test_device(mock_device_level) +local function test_init_tvoc() + local subscribed_attributes = { + [capabilities.airQualityHealthConcern.ID] = { + clusters.AirQuality.attributes.AirQuality + }, + [capabilities.temperatureMeasurement.ID] = { + clusters.TemperatureMeasurement.attributes.MeasuredValue, + clusters.TemperatureMeasurement.attributes.MinMeasuredValue, + clusters.TemperatureMeasurement.attributes.MaxMeasuredValue + }, + [capabilities.relativeHumidityMeasurement.ID] = { + clusters.RelativeHumidityMeasurement.attributes.MeasuredValue + }, + [capabilities.tvocMeasurement.ID] = { + clusters.TotalVolatileOrganicCompoundsConcentrationMeasurement.attributes.MeasuredValue, + clusters.TotalVolatileOrganicCompoundsConcentrationMeasurement.attributes.MeasurementUnit, + }, + } + initialize_mock_device(mock_device_tvoc, subscribed_attributes) end local function test_init_co_co2() @@ -419,35 +451,70 @@ local function test_init_co_co2() }, } - local subscribe_request = nil - for _, attributes in pairs(attr_co) do - for _, attribute in ipairs(attributes) do - if subscribe_request == nil then - subscribe_request = attribute:subscribe(mock_device_co) - else - subscribe_request:merge(attribute:subscribe(mock_device_co)) - end - end - end + initialize_mock_device(mock_device_co, attr_co) + initialize_mock_device(mock_device_co2, attr_co2) +end - test.socket.matter:__expect_send({mock_device_co.id, subscribe_request}) - test.mock_device.add_test_device(mock_device_co) - subscribe_request = nil - for _, attributes in pairs(attr_co2) do - for _, attribute in ipairs(attributes) do - if subscribe_request == nil then - subscribe_request = attribute:subscribe(mock_device_co2) - else - subscribe_request:merge(attribute:subscribe(mock_device_co2)) - end - end +-- run the profile configuration tests +local function test_aqs_device_type_do_configure(generic_mock_device, expected_profile) + test.socket.device_lifecycle:__queue_receive({generic_mock_device.id, "doConfigure"}) + test.socket.matter:__expect_send({generic_mock_device.id, clusters.CarbonMonoxideConcentrationMeasurement.attributes.MeasurementUnit:read()}) + test.socket.matter:__expect_send({generic_mock_device.id, clusters.CarbonDioxideConcentrationMeasurement.attributes.MeasurementUnit:read()}) + test.socket.matter:__expect_send({generic_mock_device.id, clusters.NitrogenDioxideConcentrationMeasurement.attributes.MeasurementUnit:read()}) + test.socket.matter:__expect_send({generic_mock_device.id, clusters.OzoneConcentrationMeasurement.attributes.MeasurementUnit:read()}) + test.socket.matter:__expect_send({generic_mock_device.id, clusters.FormaldehydeConcentrationMeasurement.attributes.MeasurementUnit:read()}) + test.socket.matter:__expect_send({generic_mock_device.id, clusters.Pm1ConcentrationMeasurement.attributes.MeasurementUnit:read()}) + test.socket.matter:__expect_send({generic_mock_device.id, clusters.Pm25ConcentrationMeasurement.attributes.MeasurementUnit:read()}) + test.socket.matter:__expect_send({generic_mock_device.id, clusters.Pm10ConcentrationMeasurement.attributes.MeasurementUnit:read()}) + test.socket.matter:__expect_send({generic_mock_device.id, clusters.RadonConcentrationMeasurement.attributes.MeasurementUnit:read()}) + test.socket.matter:__expect_send({generic_mock_device.id, clusters.TotalVolatileOrganicCompoundsConcentrationMeasurement.attributes.MeasurementUnit:read()}) + generic_mock_device:expect_metadata_update({ profile = expected_profile }) + generic_mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) +end + +test.register_coroutine_test( + "Configure should read units from device and profile change as needed", + function() + test_aqs_device_type_do_configure(mock_device, "aqs-temp-humidity-all-level-all-meas") end +) + +test.register_coroutine_test( + "Configure should read units from device and profile change to common clusters profile if applicable", + function() + test_aqs_device_type_do_configure(mock_device_common, "aqs-temp-humidity-co2-pm25-tvoc-meas") + end, + { test_init = test_init_common } +) + +test.register_coroutine_test( + "Configure should read units from device and profile change as needed", + function() + test_aqs_device_type_do_configure(mock_device_level, "aqs-temp-humidity-all-level") + end, + { test_init = test_init_level } +) + +test.register_coroutine_test( + "Configure should not catch co2, only co in the first check", + function() + test_aqs_device_type_do_configure(mock_device_co, "aqs-temp-humidity-all-meas") + test_aqs_device_type_do_configure(mock_device_co2, "aqs-temp-humidity-co2-pm25-tvoc-meas") + end, + { test_init = test_init_co_co2 } +) + +test.register_coroutine_test( + "Device should profile to aqs-temp-humidity-tvoc-meas", + function() + test_aqs_device_type_do_configure(mock_device_tvoc, "aqs-temp-humidity-tvoc-meas") + end, + { test_init = test_init_tvoc } +) - test.socket.matter:__expect_send({mock_device_co2.id, subscribe_request}) - test.mock_device.add_test_device(mock_device_co2) -end +-- run general tests test.register_message_test( "Temperature reports should generate correct messages", { @@ -697,98 +764,5 @@ test.register_coroutine_test( end ) -test.register_coroutine_test( - "Configure should read units from device and profile change as needed", - function() - test.socket.device_lifecycle:__queue_receive({ mock_device.id, "doConfigure" }) - test.socket.matter:__expect_send({mock_device.id, clusters.CarbonMonoxideConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device.id, clusters.CarbonDioxideConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device.id, clusters.NitrogenDioxideConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device.id, clusters.OzoneConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device.id, clusters.FormaldehydeConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device.id, clusters.Pm1ConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device.id, clusters.Pm25ConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device.id, clusters.Pm10ConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device.id, clusters.RadonConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device.id, clusters.TotalVolatileOrganicCompoundsConcentrationMeasurement.attributes.MeasurementUnit:read()}) - mock_device:expect_metadata_update({ profile = "aqs-temp-humidity-all-level-all-meas" }) - mock_device:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - end -) - -test.register_coroutine_test( - "Configure should read units from device and profile change to common clusters profile if applicable", - function() - test.socket.device_lifecycle:__queue_receive({ mock_device_common.id, "doConfigure" }) - test.socket.matter:__expect_send({mock_device_common.id, clusters.CarbonMonoxideConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_common.id, clusters.CarbonDioxideConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_common.id, clusters.NitrogenDioxideConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_common.id, clusters.OzoneConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_common.id, clusters.FormaldehydeConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_common.id, clusters.Pm1ConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_common.id, clusters.Pm25ConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_common.id, clusters.Pm10ConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_common.id, clusters.RadonConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_common.id, clusters.TotalVolatileOrganicCompoundsConcentrationMeasurement.attributes.MeasurementUnit:read()}) - mock_device_common:expect_metadata_update({ profile = "aqs-temp-humidity-co2-pm25-tvoc-meas" }) - mock_device_common:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - end, - { test_init = test_init_common } -) - -test.register_coroutine_test( - "Configure should read units from device and profile change as needed", - function() - test.socket.device_lifecycle:__queue_receive({ mock_device_level.id, "doConfigure" }) - test.socket.matter:__expect_send({mock_device_level.id, clusters.CarbonMonoxideConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_level.id, clusters.CarbonDioxideConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_level.id, clusters.NitrogenDioxideConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_level.id, clusters.OzoneConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_level.id, clusters.FormaldehydeConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_level.id, clusters.Pm1ConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_level.id, clusters.Pm25ConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_level.id, clusters.Pm10ConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_level.id, clusters.RadonConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_level.id, clusters.TotalVolatileOrganicCompoundsConcentrationMeasurement.attributes.MeasurementUnit:read()}) - mock_device_level:expect_metadata_update({ profile = "aqs-temp-humidity-all-level" }) - mock_device_level:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - end, - { test_init = test_init_level } -) - - -test.register_coroutine_test( - "Configure should not catch co2, only co in the first check", - function() - test.socket.device_lifecycle:__queue_receive({ mock_device_co.id, "doConfigure" }) - test.socket.matter:__expect_send({mock_device_co.id, clusters.CarbonMonoxideConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_co.id, clusters.CarbonDioxideConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_co.id, clusters.NitrogenDioxideConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_co.id, clusters.OzoneConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_co.id, clusters.FormaldehydeConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_co.id, clusters.Pm1ConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_co.id, clusters.Pm25ConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_co.id, clusters.Pm10ConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_co.id, clusters.RadonConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_co.id, clusters.TotalVolatileOrganicCompoundsConcentrationMeasurement.attributes.MeasurementUnit:read()}) - mock_device_co:expect_metadata_update({ profile = "aqs-temp-humidity-all-meas" }) - mock_device_co:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - - test.socket.device_lifecycle:__queue_receive({ mock_device_co2.id, "doConfigure" }) - test.socket.matter:__expect_send({mock_device_co2.id, clusters.CarbonMonoxideConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_co2.id, clusters.CarbonDioxideConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_co2.id, clusters.NitrogenDioxideConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_co2.id, clusters.OzoneConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_co2.id, clusters.FormaldehydeConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_co2.id, clusters.Pm1ConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_co2.id, clusters.Pm25ConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_co2.id, clusters.Pm10ConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_co2.id, clusters.RadonConcentrationMeasurement.attributes.MeasurementUnit:read()}) - test.socket.matter:__expect_send({mock_device_co2.id, clusters.TotalVolatileOrganicCompoundsConcentrationMeasurement.attributes.MeasurementUnit:read()}) - mock_device_co2:expect_metadata_update({ profile = "aqs-temp-humidity-co2-pm25-tvoc-meas" }) - mock_device_co2:expect_metadata_update({ provisioning_state = "PROVISIONED" }) - end, - { test_init = test_init_co_co2 } -) - +-- run tests test.run_registered_tests()