Skip to content

Commit

Permalink
Merge pull request #202 from nomis/unbind-ep
Browse files Browse the repository at this point in the history
Support unbinding specific endpoints in binds_remove_all
  • Loading branch information
mdeweerd authored Sep 17, 2023
2 parents 68f94c1 + d023845 commit e1f9600
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 18 deletions.
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -925,8 +925,10 @@ data:
command_data: 00:12:4b:00:01:6a:41:0c
# Optional - name of generated event when done
event_done: zhat_event
# Optional - Endpoint or list of endpoints for which to remove bindings
# endpoint: [20, 30]
# Optional - Cluster or list of clusters for which to remove bindings
# cluster: [ 0x0006, 0x0300]
# cluster: [0x0006, 0x0300]
# Optional
tries: 100
```
Expand All @@ -947,8 +949,10 @@ data:
ieee: entity.my_thermostat_entity
# Optional - name of generated event when done
event_done: zhat_event
# Optional - Endpoint or list of endpoints for which to remove bindings
# endpoint: [20, 30]
# Optional - Cluster or list of clusters for which to remove bindings
# cluster: [ 0x0006, 0x0300]
# cluster: [0x0006, 0x0300]
# Optional
tries: 100
```
Expand Down
6 changes: 6 additions & 0 deletions custom_components/zha_toolkit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,9 @@
vol.Optional(ATTR_COMMAND_DATA): vol.Any(
cv.entity_id_or_uuid, t.EUI64.convert
),
vol.Optional(P.ENDPOINT): vol.Any(
vol.Range(0, 255), [vol.Range(0, 255)]
),
vol.Optional(P.CLUSTER): vol.Any(
vol.Range(0, 0xFFFF), [vol.Range(0, 0xFFFF)]
),
Expand Down Expand Up @@ -475,6 +478,9 @@
vol.Required(ATTR_IEEE): vol.Any(
cv.entity_id_or_uuid, t.EUI64.convert
),
vol.Optional(P.ENDPOINT): vol.Any(
vol.Range(0, 255), [vol.Range(0, 255)]
),
vol.Optional(P.CLUSTER): vol.Any(
vol.Range(0, 0xFFFF), [vol.Range(0, 0xFFFF)]
),
Expand Down
38 changes: 30 additions & 8 deletions custom_components/zha_toolkit/binds.py
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,17 @@ async def binds_remove_all(
# as the field is not ok.
tgt_ieee = (await u.get_device(app, listener, data)).ieee

# Determine endpoints to unbind
endpoints = []

u_endpoint_id = params[p.EP_ID]
if u_endpoint_id is not None and u_endpoint_id != "":
if not isinstance(u_endpoint_id, list):
u_endpoint_id = [u_endpoint_id]

# unbind user provided endpoints instead
endpoints = u_endpoint_id

# Determine clusters to unbind
clusters = []

Expand Down Expand Up @@ -478,6 +489,7 @@ async def binds_remove_all(
if addr_mode == 1:
# group
src_ieee = t.EUI64.convert(binding["src"])
ep_id = u.str2int(binding["src_ep"])
cluster_id = u.str2int(binding["cluster_id"])

dst_addr = MultiAddress()
Expand All @@ -488,14 +500,18 @@ async def binds_remove_all(
dst_ieee = t.EUI64.convert(binding["dst"]["dst_ieee"])
dst_addr.ieee = dst_ieee

if (tgt_ieee is None or dst_ieee == tgt_ieee) and (
len(clusters) == 0 or cluster_id in clusters
):
match_filter = (
(tgt_ieee is None or dst_ieee == tgt_ieee)
and (len(endpoints) == 0 or ep_id in endpoints)
and (len(clusters) == 0 or cluster_id in clusters)
)

if match_filter:
res = await u.retry_wrapper(
zdo.request,
ZDOCmd.Unbind_req,
src_ieee,
binding["src_ep"],
ep_id,
cluster_id,
dst_addr,
tries=params[p.TRIES],
Expand All @@ -511,18 +527,24 @@ async def binds_remove_all(
dst_addr.addrmode = addr_mode
dst_addr.ieee = dst_ieee
dst_addr.endpoint = t.uint8_t(binding["dst"]["dst_ep"])
ep_id = u.str2int(binding["src_ep"])
cluster_id = u.str2int(binding["cluster_id"])
# LOGGER.debug(
# f"filter {tgt_ieee} {dst_ieee} {clusters} {cluster_id}"
# )
if (tgt_ieee is None or dst_ieee == tgt_ieee) and (
len(clusters) == 0 or cluster_id in clusters
):

match_filter = (
(tgt_ieee is None or dst_ieee == tgt_ieee)
and (len(endpoints) == 0 or ep_id in endpoints)
and (len(clusters) == 0 or cluster_id in clusters)
)

if match_filter:
res = await u.retry_wrapper(
zdo.request,
ZDOCmd.Unbind_req,
src_ieee,
binding["src_ep"],
ep_id,
cluster_id,
dst_addr,
tries=params[p.TRIES],
Expand Down
34 changes: 28 additions & 6 deletions custom_components/zha_toolkit/services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1061,12 +1061,23 @@ binds_remove_all:
selector:
entity:
integration: zha
endpoint:
name: Target Endpoint
description: >-
When provided, remove only bindings for this endpoint or list of endpoints
(single value or list. Example: 20 or [20, 30])
Otherwise: removes bindings for all endpoints
selector:
number:
min: 0
max: 255
mode: box
cluster:
name: Target Cluster
description: >-
When provided, remove only bindings for this cluster or list of clusters (
single value or list. Example: 0x0200 or [ 0x200, 0x300] )
Otherwise\: removes bindings for all clusters
When provided, remove only bindings for this cluster or list of clusters
(single value or list. Example: 0x0200 or [0x200, 0x300])
Otherwise: removes bindings for all clusters
selector:
number:
min: 0
Expand Down Expand Up @@ -2205,12 +2216,23 @@ unbind_coordinator:
selector:
entity:
integration: zha
endpoint:
name: Target Endpoint
description: >-
When provided, remove only bindings for this endpoint or list of endpoints
(single value or list. Example: 20 or [20, 30])
Otherwise: removes bindings for all endpoints
selector:
number:
min: 0
max: 255
mode: box
cluster:
name: Target Cluster
description: >-
When provided, remove only bindings for this cluster or list of clusters (
single value or list. Example: 0x0200 or [ 0x200, 0x300] )
Otherwise\: removes bindings for all clusters
When provided, remove only bindings for this cluster or list of clusters
(single value or list. Example: 0x0200 or [0x200, 0x300])
Otherwise: removes bindings for all clusters
selector:
number:
min: 0
Expand Down
12 changes: 10 additions & 2 deletions custom_components/zha_toolkit/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -584,9 +584,13 @@
"name": "Remove Bindings with This Device",
"description": "When provided, remove only bindings towards this device (Entity name, device name, or IEEE address of the binding destination)"
},
"endpoint": {
"name": "Target Endpoint",
"description": "When provided, remove only bindings for this endpoint or list of endpoints (single value or list. Example: 20 or [20, 30]) Otherwise: removes bindings for all endpoints"
},
"cluster": {
"name": "Target Cluster",
"description": "When provided, remove only bindings for this cluster or list of clusters ( single value or list. Example: 0x0200 or [ 0x200, 0x300] ) Otherwise\\: removes bindings for all clusters"
"description": "When provided, remove only bindings for this cluster or list of clusters (single value or list. Example: 0x0200 or [0x200, 0x300]) Otherwise: removes bindings for all clusters"
},
"tries": {
"name": "Tries",
Expand Down Expand Up @@ -1274,9 +1278,13 @@
"name": "Device Reference",
"description": "Entity name, device name, or IEEE address of the node to execute command"
},
"endpoint": {
"name": "Target Endpoint",
"description": "When provided, remove only bindings for this endpoint or list of endpoints (single value or list. Example: 20 or [20, 30]) Otherwise: removes bindings for all endpoints"
},
"cluster": {
"name": "Target Cluster",
"description": "When provided, remove only bindings for this cluster or list of clusters ( single value or list. Example: 0x0200 or [ 0x200, 0x300] ) Otherwise\\: removes bindings for all clusters"
"description": "When provided, remove only bindings for this cluster or list of clusters (single value or list. Example: 0x0200 or [0x200, 0x300]) Otherwise: removes bindings for all clusters"
},
"tries": {
"name": "Tries",
Expand Down

0 comments on commit e1f9600

Please sign in to comment.