Skip to content
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

add support for generic zigbee multi-switch #1922

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

pInksenberg
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

add support for generic zigbee multi-switch

Summary of Completed Tests

Copy link

Copy link

github-actions bot commented Feb 11, 2025

Test Results

   64 files    409 suites   0s ⏱️
2 033 tests 2 031 ✅ 0 💤 2 ❌
3 512 runs  3 510 ✅ 0 💤 2 ❌

For more details on these failures, see this check.

Results for commit c7c1799.

♻️ This comment has been updated with latest results.

Copy link

github-actions bot commented Feb 11, 2025

File Coverage
All files 89%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/zigbee-switch/src/zigbee-switch-power/vimar/init.lua 70%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/zigbee-switch/src/inovelli-vzm31-sn/init.lua 37%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/zigbee-switch/src/sinope-dimmer/init.lua 91%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/zigbee-switch/src/preferences.lua 97%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/zigbee-switch/src/init.lua 87%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/zigbee-switch/src/zigbee-dimmer-power-energy/enbrighten-metering-dimmer/init.lua 91%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/zigbee-switch/src/aqara/init.lua 95%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/zigbee-switch/src/aqara/multi-switch/init.lua 87%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/zigbee-switch/src/aqara-light/init.lua 93%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/zigbee-switch/src/jasco/init.lua 94%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/zigbee-switch/src/ge-link-bulb/init.lua 95%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/zigbee-switch/src/tuya-multi/init.lua 48%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/zigbee-switch/src/aqara/version/init.lua 94%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/zigbee-switch/src/wallhero/init.lua 97%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/zigbee-switch/src/zigbee-dimmer-power-energy/init.lua 73%
/home/runner/work/SmartThingsEdgeDrivers/SmartThingsEdgeDrivers/drivers/SmartThings/zigbee-switch/src/zigbee-switch-power/aurora-relay/init.lua 80%

Minimum allowed coverage is 90%

Generated by 🐒 cobertura-action against c7c1799

})
end

local function device_added(driver, device, event)
Copy link
Contributor

Choose a reason for hiding this comment

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

This added function is now going to be run for all devices joined to the zigbee-switch driver, I don't think we should be making a change that affects all those other devices.

Copy link
Contributor

@varzac varzac Feb 12, 2025

Choose a reason for hiding this comment

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

This should be moved to the subdriver as this should only be run for the tuya devices.

EDIT: Oh, I see it was changed to not include the custom stuff so this may be fine to leave in the base driver since it is pretty generic.

Copy link
Collaborator

@kdbang kdbang Feb 13, 2025

Choose a reason for hiding this comment

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

I figured out which devices are affected by this code in wwst certified devices. Most of devices that have multi endpoint has their own added_handler. but there is one device that doesn't have sub-driver.

- id: "ubisys/S2 (5502)"
    deviceLabel: ubisys S2
    manufacturer: ubisys
    model: "S2 (5502)"
    deviceProfileName: switch-power-firmware-2

ubisys S2 is multi component device.

name: switch-power-firmware-2
components:
  - id: main
    capabilities:
      - id: powerMeter
        version: 1
      - id: firmwareUpdate
        version: 1
      - id: refresh
        version: 1
    categories:
      - name: Switch
  - id: switch1
    capabilities:
      - id: switch
        version: 1
    categories:
      - name: Switch
  - id: switch2
    capabilities:
      - id: switch
        version: 1
    categories:
      - name: Switch

the device will be affected by this code. we need to avoid these code for this 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.

we will add S2 device(MCD) fingerprint in added handler to avoid running our logic.

Copy link
Contributor

Choose a reason for hiding this comment

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

I think this is the last hurdle for this PR. @varzac @tpmanley Do you have any idea to filter this device in added handler? This device doesn't have switch capability in main component, how about checking this condition?

device.profile.components.main.capabilities.switch == nil

Is it too specific?

@@ -85,6 +100,133 @@ local device_init = function(self, device)
end
end


local function send_discover_command(device)
local discover_attribute_id = 0x0c
Copy link
Contributor

@varzac varzac Feb 11, 2025

Choose a reason for hiding this comment

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

This looks to be a command ID and not an attribute ID, and this command is not defined in the ZCL spec, which makes it seem like a manufacturer specific function, and we should not be sending a manufacturer specific command to every device that is onboarded.

Copy link
Contributor

@tpmanley tpmanley Feb 11, 2025

Choose a reason for hiding this comment

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

I think the intention is to send the global command Discovery Attributes which does have a command ID of 0x0C

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, I had forgotten the default for the frame control was a global command. So that explains the command. I'm still not sure what the reason for sending it is.

device:send(send_message)
end

local function read_attribute_function(device, cluster_id, attr_id)
Copy link
Contributor

Choose a reason for hiding this comment

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

A function like this is already defined in BasicCluster.read_attribute so you don't need to redifine it here.

return result
end

local function all_zigbee_message_handler(self, message_channel)
Copy link
Contributor

Choose a reason for hiding this comment

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

This is going to change how EVERY message processed by ANY Zigbee Switch on the platform is handled. I do not think we should make this change.

@pInksenberg pInksenberg force-pushed the add_support_for_zigbee_mutli-switch branch from bc2da4c to fc3b686 Compare February 12, 2025 10:56
end

local function discover_response_message_handler(driver, device, zb_rx)
if zb_rx.address_header.cluster.value == clusters.Basic.ID and zb_rx.body.zcl_header.cmd.value == DISCOVER_ATTR_RSP_ID then
Copy link
Contributor

Choose a reason for hiding this comment

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

If this function is called, both of these have already been validated, so you don't need to check again here.

device:send(send_message)
end

local function read_attribute_function(device, cluster_id, attr_id)
Copy link
Contributor

Choose a reason for hiding this comment

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

As mentioned, this code is already defined in the zigbee cluster_base, so you can just require the BasicCluster and then use BasicCluster.read_attribute(device, cluster_id, attr_id) instead of duplicating the code here.

end
table.remove(bytes, 1) -- remove first type which means discover attribute command is completed
local result = {}
for i = 1, #bytes, 3 do -- remove data type information
Copy link
Contributor

@varzac varzac Feb 12, 2025

Choose a reason for hiding this comment

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

I think this loop can be simplified by using the buf lib local buf = buf_lib.Reader(data) and then you can use

https://github.ecodesamsung.com/iot-hub/scripting-engine/blob/main/lua_libs/st/zigbee/data_types/AttributeId.lua
and
https://github.ecodesamsung.com/iot-hub/scripting-engine/blob/main/lua_libs/st/zigbee/data_types/ZigbeeDataType.lua

using their deserialize functions.

So something like

local attr_list = {}
while buf:remain() > 0 do
     attr_list[#attr_list+1] = AttributeId.deserialize(buf)
     local type_info = ZigbeeDataType.deserialize(buf)
end

you could also create a definition for the discover attribute response global command similar to https://developer.smartthings.com/docs/edge-device-drivers/zigbee/zcl/zcl_commands.html#read-attribute-response so that we can support this from any driver instead of custom in this driver.

local TUYA_MFR_HEADER = "_TZ"

local function is_tuya_products(opts, driver, device)
if string.sub(device:get_manufacturer(),1,3) == TUYA_MFR_HEADER then -- if it is a tuya device, then send the magic packet
Copy link
Contributor

Choose a reason for hiding this comment

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

Should we also check that there is more than 1 zigbee endpoint since this handling is only for multi switch devices?

Copy link
Collaborator

Choose a reason for hiding this comment

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

@pInksenberg can you address @varzac 's comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure, we will add this logic in next commit tonight.

@@ -85,6 +89,40 @@ local device_init = function(self, device)
end
end

local function device_added(driver, device, event)
device:set_find_child(find_child)
Copy link
Contributor

Choose a reason for hiding this comment

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

I would move setting this function to only be set if at least 1 child device is created.

@pInksenberg pInksenberg force-pushed the add_support_for_zigbee_mutli-switch branch from fc3b686 to 09e3de1 Compare February 13, 2025 10:11
@pInksenberg pInksenberg force-pushed the add_support_for_zigbee_mutli-switch branch from 09e3de1 to c7c1799 Compare February 13, 2025 10:24
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