Skip to content

Commit

Permalink
Merge pull request #135 from mdeweerd/dev
Browse files Browse the repository at this point in the history
Improve binding to coordinator, do not require cluster to be present
  • Loading branch information
mdeweerd authored Feb 1, 2023
2 parents 1215562 + b922e53 commit 062771d
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 13 deletions.
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -650,9 +650,15 @@ The default list of binding clusters is currently as follows:
### `bind_ieee`: Bind matching cluster to another device

Bind all available default and matching clusters from `ieee` to
`command_data` on all endpoints. By defaault only binds clusters in the
`command_data` on all endpoints.\
Binds to the coordinator if
`command_data` is not set or 0.\
By default only binds cluster types in the
internal list, i.e. OnOff, Level and Color Control clusters.

The cluster must exist on both devices, except when the coordinator is the
target.

If you set the `cluster`, you can bind another cluster type and only that
cluster will be bound (both in and out clusters).

Expand All @@ -662,6 +668,7 @@ Use `binds_get` to verify that the configuration worked.
service: zha_toolkit.bind_ieee
data:
ieee: entity.my_thermostat_entity
# Optional, when not set or 0, bind to the coordinator.
command_data: 00:12:4b:00:22:08:ed:1a
# Optional, if you want to bind a cluster not internally selected.
cluster: 0x0006
Expand Down
27 changes: 15 additions & 12 deletions custom_components/zha_toolkit/binds.py
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ async def bind_ieee(
# when command_data is set to 0 or false, bind to coordinator
data = app.ieee

isCoordinatorTarget = str(data) == str(app.ieee)

dst_dev = await u.get_device(app, listener, data)

zdo = src_dev.zdo
Expand All @@ -244,15 +246,15 @@ async def bind_ieee(
and (u_epid is None or u_epid == ep_id)
]
LOGGER.debug(
"0x%04x: got the %s endpoints for %s cluster",
"0x%04X: got endpoints %s for out-cluster 0x%04X",
src_dev.nwk,
src_endpoints,
src_out_cluster,
)

if not src_endpoints:
LOGGER.debug(
"0x%04x: skipping %0x04X cluster as non present",
"0x%04X: skipping out-cluster 0x%04X as non present",
src_dev.nwk,
src_out_cluster,
)
Expand All @@ -266,7 +268,7 @@ async def bind_ieee(
for ep_id, ep in dst_dev.endpoints.items():
if ep_id == 0:
continue
if src_out_cluster in ep.in_clusters:
if isCoordinatorTarget or (src_out_cluster in ep.in_clusters):
dst_epid = ep_id
break
if not dst_epid:
Expand All @@ -275,7 +277,7 @@ async def bind_ieee(

for src_ep in src_endpoints:
LOGGER.debug(
"0x%04x: binding %s, ep: %s, cluster: 0x%04X to %s dev %s ep",
"0x%04x: binding %s/EP:%s, out-cluster 0x%04X to %s/EP:%s",
src_dev.nwk,
str(src_dev.ieee),
src_ep,
Expand Down Expand Up @@ -306,15 +308,15 @@ async def bind_ieee(
and (u_epid is None or u_epid == ep_id)
]
LOGGER.debug(
"0x%04x: got the %s endpoints for %s cluster",
"0x%04X: got endpoints %s for in cluster 0x%04X",
src_dev.nwk,
src_endpoints,
src_in_cluster,
)

if not src_endpoints:
LOGGER.debug(
"0x%04x: skipping %0x04X cluster as non present",
"0x%04X: skipping in-cluster 0x%04X as non present",
src_dev.nwk,
src_in_cluster,
)
Expand All @@ -323,12 +325,12 @@ async def bind_ieee(
dst_addr.addrmode = t.uint8_t(3)
dst_addr.ieee = dst_dev.ieee

# find dest ep
# Find dest ep, accept first EP if coordinator
dst_epid = None
for ep_id, ep in dst_dev.endpoints.items():
if ep_id == 0:
continue
if src_in_cluster in ep.out_clusters:
if isCoordinatorTarget or (src_in_cluster in ep.out_clusters):
dst_epid = ep_id
break
if not dst_epid:
Expand All @@ -337,7 +339,7 @@ async def bind_ieee(

for src_ep in src_endpoints:
LOGGER.debug(
"0x%04x: binding %s, ep: %s, cluster: 0x%04X to %s dev %s ep",
"0x%04X: binding %s/EP:%s, in-cluster: 0x%04X to %s/EP:%s",
src_dev.nwk,
str(src_dev.ieee),
src_ep,
Expand All @@ -359,13 +361,14 @@ async def bind_ieee(
bind_result["result"] = res
results[src_ep] = bind_result
LOGGER.debug(
"0x%04x: binding ieee %s: %s",
"0x%04X: binding ieee %s: %s",
src_dev.nwk,
str(dst_dev.ieee),
res,
)

event_data["result"] = results
event_data["success"] = len(results) != 0


async def unbind_coordinator(
Expand Down Expand Up @@ -429,8 +432,8 @@ async def binds_remove_all(
addr_mode = binding["dst"]["addrmode"]

res = None
# Note, the code belowe is essentially two times the same
# but the goal is to make a distinciont between group
# Note, the code below is essentially two times the same
# but the goal is to make a distincion between group
# and ieee addressing for testing/evolutions.
if addr_mode == 1:
# group
Expand Down

0 comments on commit 062771d

Please sign in to comment.