From c37b3238337457dbb0767247f3b32dfd9af70b92 Mon Sep 17 00:00:00 2001 From: Tom Manley Date: Sat, 4 May 2024 15:06:44 -0500 Subject: [PATCH 1/4] SmartSense Multi: Fix handling of large negative threeAxis values The convert_to_signedInt16 function had a bug preventing it from handling large negative threeAxis values. This would impact the garage door handling since in the typical orientation the sensor will report approximately -1000 for the Z axis when the door is open. https://smartthings.atlassian.net/browse/CHAD-13097 --- .../src/multi-sensor/multi_utils.lua | 2 +- .../src/test/test_smartsense_multi.lua | 60 +++++++++++++++++-- 2 files changed, 55 insertions(+), 7 deletions(-) diff --git a/drivers/SmartThings/zigbee-contact/src/multi-sensor/multi_utils.lua b/drivers/SmartThings/zigbee-contact/src/multi-sensor/multi_utils.lua index 863c544d6d..e24ec1097b 100644 --- a/drivers/SmartThings/zigbee-contact/src/multi-sensor/multi_utils.lua +++ b/drivers/SmartThings/zigbee-contact/src/multi-sensor/multi_utils.lua @@ -138,7 +138,7 @@ multi_utils.convert_to_signedInt16 = function(byte1, byte2) local finalValue local swapped = (byte2 << 8) | byte1 local sign_mask = 0x8000 - local int16mask = 0xFF + local int16mask = 0xFFFF local isNegative = (swapped & sign_mask) >> 15 if(isNegative == 1) then diff --git a/drivers/SmartThings/zigbee-contact/src/test/test_smartsense_multi.lua b/drivers/SmartThings/zigbee-contact/src/test/test_smartsense_multi.lua index ddb167a9dd..718359d3c3 100644 --- a/drivers/SmartThings/zigbee-contact/src/test/test_smartsense_multi.lua +++ b/drivers/SmartThings/zigbee-contact/src/test/test_smartsense_multi.lua @@ -336,26 +336,74 @@ test.register_coroutine_test( ) test.register_coroutine_test( - "Report from cluster 0xFC03, command 0x05 should be handled as: threeAxis(1050, -3, 9)", + "Report from cluster 0xFC03, command 0x05 should be handled as: threeAxis(1050, 3, 9)", function() test.socket.zigbee:__queue_receive({ mock_device.id, - build_three_axis_report_message(mock_device, "\x1A\x04\xFD\xFF\x09\x00") + build_three_axis_report_message(mock_device, "\x1A\x04\x03\x00\x09\x00") }) test.socket.capability:__set_channel_ordering("relaxed") - test.socket.capability:__expect_send(mock_device:generate_test_message("main", capabilities.threeAxis.threeAxis({1050, -3, 9})) ) + test.socket.capability:__expect_send(mock_device:generate_test_message("main", capabilities.threeAxis.threeAxis({1050, 3, 9})) ) end ) test.register_coroutine_test( - "Report from cluster 0xFC03, command 0x05 should be handled as: threeAxis(1123,-130,-24)", + "Report from cluster 0xFC03, command 0x05 should be handled as: threeAxis(-1050, -3, -9)", function() test.socket.zigbee:__queue_receive({ mock_device.id, - build_three_axis_report_message(mock_device, "\x63\x04\x7E\xFF\xE8\xFF") + build_three_axis_report_message(mock_device, "\xE6\xFB\xFD\xFF\xF7\xFF") }) test.socket.capability:__set_channel_ordering("relaxed") - test.socket.capability:__expect_send(mock_device:generate_test_message("main", capabilities.threeAxis.threeAxis({1123, -130, -24})) ) + test.socket.capability:__expect_send(mock_device:generate_test_message("main", capabilities.threeAxis.threeAxis({-1050, -3, -9})) ) + end +) + +test.register_coroutine_test( + "Report from cluster 0xFC03, command 0x05 should be handled as: threeAxis(10, 1020, 7)", + function() + test.socket.zigbee:__queue_receive({ + mock_device.id, + build_three_axis_report_message(mock_device, "\x0A\x00\xFC\x03\x07\x00") + }) + test.socket.capability:__set_channel_ordering("relaxed") + test.socket.capability:__expect_send(mock_device:generate_test_message("main", capabilities.threeAxis.threeAxis({10, 1020, 7})) ) + end +) + +test.register_coroutine_test( + "Report from cluster 0xFC03, command 0x05 should be handled as: threeAxis(-10, -1020, -7)", + function() + test.socket.zigbee:__queue_receive({ + mock_device.id, + build_three_axis_report_message(mock_device, "\xF6\xFF\x04\xFC\xF9\xFF") + }) + test.socket.capability:__set_channel_ordering("relaxed") + test.socket.capability:__expect_send(mock_device:generate_test_message("main", capabilities.threeAxis.threeAxis({-10, -1020, -7})) ) + end +) + +test.register_coroutine_test( + "Report from cluster 0xFC03, command 0x05 should be handled as: threeAxis(116, 4, 1003)", + function() + test.socket.zigbee:__queue_receive({ + mock_device.id, + build_three_axis_report_message(mock_device, "\x74\x00\x04\x00\xEB\x03") + }) + test.socket.capability:__set_channel_ordering("relaxed") + test.socket.capability:__expect_send(mock_device:generate_test_message("main", capabilities.threeAxis.threeAxis({116, 4, 1003})) ) + end +) + +test.register_coroutine_test( + "Report from cluster 0xFC03, command 0x05 should be handled as: threeAxis(-116, -4, -1003)", + function() + test.socket.zigbee:__queue_receive({ + mock_device.id, + build_three_axis_report_message(mock_device, "\x8C\xFF\xFC\xFF\x15\xFC") + }) + test.socket.capability:__set_channel_ordering("relaxed") + test.socket.capability:__expect_send(mock_device:generate_test_message("main", capabilities.threeAxis.threeAxis({-116, -4, -1003})) ) end ) From 0431b6a8eff6810b46216be8cfc57fce57d0286c Mon Sep 17 00:00:00 2001 From: lelandblue <79465613+lelandblue@users.noreply.github.com> Date: Mon, 6 May 2024 09:48:01 -0400 Subject: [PATCH 2/4] new-device-nanoleaf-indoor-lights --- drivers/SmartThings/matter-switch/fingerprints.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/SmartThings/matter-switch/fingerprints.yml b/drivers/SmartThings/matter-switch/fingerprints.yml index c0f58df2b4..c5504e9899 100644 --- a/drivers/SmartThings/matter-switch/fingerprints.yml +++ b/drivers/SmartThings/matter-switch/fingerprints.yml @@ -203,6 +203,11 @@ matterManufacturer: vendorId: 0x115A productId: 0x711 deviceProfileName: light-color-level-2700K-6500K + - id: "4442/72" + deviceLabel: Essentials Indoor Lights + vendorId: 0x115A + productId: 0x0048 + deviceProfileName: light-level-colorTemperature-2200K-6500K #SONOFF - id: "SONOFF MINIR4M" deviceLabel: Smart Plug-in Unit From a309049c6d510c8f5808d691a493a94f1d03e4c8 Mon Sep 17 00:00:00 2001 From: lelandblue <79465613+lelandblue@users.noreply.github.com> Date: Mon, 6 May 2024 09:52:17 -0400 Subject: [PATCH 3/4] remove-nanoleaf-indoor-from-main --- drivers/SmartThings/matter-switch/fingerprints.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/SmartThings/matter-switch/fingerprints.yml b/drivers/SmartThings/matter-switch/fingerprints.yml index c5504e9899..c0f58df2b4 100644 --- a/drivers/SmartThings/matter-switch/fingerprints.yml +++ b/drivers/SmartThings/matter-switch/fingerprints.yml @@ -203,11 +203,6 @@ matterManufacturer: vendorId: 0x115A productId: 0x711 deviceProfileName: light-color-level-2700K-6500K - - id: "4442/72" - deviceLabel: Essentials Indoor Lights - vendorId: 0x115A - productId: 0x0048 - deviceProfileName: light-level-colorTemperature-2200K-6500K #SONOFF - id: "SONOFF MINIR4M" deviceLabel: Smart Plug-in Unit From 9418b11a0a3ec9ed785334cde528ba08d9a1c513 Mon Sep 17 00:00:00 2001 From: Tom Manley Date: Sun, 5 May 2024 12:18:57 -0500 Subject: [PATCH 4/4] zigbee-contact: Fix garage door handling for SmartSense Multi The original SmartSense Multi has a different z-axis than the newer sensors. When installed on the garage door it is parallel to the ground when the door is closed and perpendicular to the ground when the door is open. For this reason it can't share the garage door handling code that the newer sensors use. This change implements the necessary custom handling and adds a unit test. https://smartthings.atlassian.net/browse/CHAD-13098 --- .../src/smartsense-multi/init.lua | 14 ++++++++- .../src/test/test_smartsense_multi.lua | 30 +++++++++++++++++++ 2 files changed, 43 insertions(+), 1 deletion(-) diff --git a/drivers/SmartThings/zigbee-contact/src/smartsense-multi/init.lua b/drivers/SmartThings/zigbee-contact/src/smartsense-multi/init.lua index 45d9521496..92fa777b7c 100644 --- a/drivers/SmartThings/zigbee-contact/src/smartsense-multi/init.lua +++ b/drivers/SmartThings/zigbee-contact/src/smartsense-multi/init.lua @@ -146,7 +146,19 @@ local function xyz_handler(driver, device, zb_rx) local x = multi_utils.convert_to_signedInt16(zb_rx.body.zcl_body.body_bytes:byte(1), zb_rx.body.zcl_body.body_bytes:byte(2)) local y = multi_utils.convert_to_signedInt16(zb_rx.body.zcl_body.body_bytes:byte(3), zb_rx.body.zcl_body.body_bytes:byte(4)) local z = multi_utils.convert_to_signedInt16(zb_rx.body.zcl_body.body_bytes:byte(5), zb_rx.body.zcl_body.body_bytes:byte(6)) - multi_utils.handle_three_axis_report(device, x, y, z) + device:emit_event(capabilities.threeAxis.threeAxis({value = {x, y, z}})) + if device.preferences["certifiedpreferences.garageSensor"] then + -- The sensor is mounted on the garage door vertically. Unlike the newer sensors, the z-axis is parallel to the ground + -- when the door is closed and perpendicular to the ground when the door is open. This is why we are using custom handling + -- instead of multi_utils.handle_three_axis_report. The values here were the same used in the original Groovy DTH + -- and in the protocol handler. + local abs_z = math.abs(z) + if abs_z > 825 then + device:emit_event(capabilities.contactSensor.contact.open()) + elseif abs_z < 100 then + device:emit_event(capabilities.contactSensor.contact.closed()) + end + end end local smartsense_multi = { diff --git a/drivers/SmartThings/zigbee-contact/src/test/test_smartsense_multi.lua b/drivers/SmartThings/zigbee-contact/src/test/test_smartsense_multi.lua index 718359d3c3..9db8033062 100644 --- a/drivers/SmartThings/zigbee-contact/src/test/test_smartsense_multi.lua +++ b/drivers/SmartThings/zigbee-contact/src/test/test_smartsense_multi.lua @@ -407,4 +407,34 @@ test.register_coroutine_test( end ) +test.register_coroutine_test( + "Correct contact events should be generated when device is mounted on garage door", + function() + test.socket.device_lifecycle():__queue_receive({mock_device.id, "init"}) + test.socket.device_lifecycle():__queue_receive(mock_device:generate_info_changed( + { + preferences = { + ["certifiedpreferences.garageSensor"] = true + } + } + )) + test.wait_for_events() + test.socket.capability:__set_channel_ordering("relaxed") + test.socket.zigbee:__queue_receive({ + mock_device.id, + build_three_axis_report_message(mock_device, "\xF6\xFF\x04\xFC\x9D\xFF") + }) + test.socket.capability:__expect_send(mock_device:generate_test_message("main", capabilities.threeAxis.threeAxis({-10, -1020, -99})) ) + test.socket.capability:__expect_send( mock_device:generate_test_message("main", capabilities.contactSensor.contact.closed())) + + test.wait_for_events() + test.socket.zigbee:__queue_receive({ + mock_device.id, + build_three_axis_report_message(mock_device, "\x8C\xFF\xFC\xFF\xC6\xFC") + }) + test.socket.capability:__expect_send(mock_device:generate_test_message("main", capabilities.threeAxis.threeAxis({-116, -4, -826})) ) + test.socket.capability:__expect_send( mock_device:generate_test_message("main", capabilities.contactSensor.contact.open())) + end +) + test.run_registered_tests() \ No newline at end of file