Repository navigation
feat: Register child devices as top level devices #1739
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
base: main
Are you sure you want to change the base?
Changes from all commits
396a673
c621e68
8ee7db7
d92fe6a
b2ff531
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -341,6 +341,10 @@ def register_device(self, device: Device, name: str | None = None) -> None: | |
| `name` parameter here. If the device conforms to a different protocol then | ||
| the parameter must be used to name it. | ||
| Children of ophyd-async devices, including signals, are also registered | ||
| under their own names, e.g. registering "stage" also registers "stage-x" | ||
| and "stage-x-velocity". | ||
| Args: | ||
| device (Device): The device to register | ||
| name (Optional[str], optional): A name for the device. Defaults to None. | ||
|
|
@@ -358,7 +362,40 @@ def register_device(self, device: Device, name: str | None = None) -> None: | |
| else: | ||
| raise KeyError(f"Must supply a name for this device: {device}") | ||
|
|
||
| existing = self.devices.get(name) | ||
| if existing is not None and existing is not device: | ||
| LOGGER.warning("Replacing existing device registered as '%s'", name) | ||
| self.devices[name] = device | ||
| self._register_children(device) | ||
|
|
||
| def _register_children( | ||
| self, device: Device, ancestor_names: frozenset[str] = frozenset() | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would it work to use |
||
| ) -> None: | ||
| """Register the children of an ophyd-async device under their own names.""" | ||
|
|
||
| if not isinstance(device, AsyncDevice): | ||
| return | ||
|
|
||
| ancestor_names = ancestor_names | {device.name} | ||
| for attr_name, child in device.children(): | ||
| if child.name: | ||
| # Some children share an ancestor's name, e.g. a motor's | ||
| # user_readback, so name these after their attribute instead | ||
| if child.name in ancestor_names: | ||
| name = f"{device.name}-{attr_name}" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does it make sense to make up a new name for a signal? If some devices is named |
||
| else: | ||
| name = child.name | ||
| existing = self.devices.setdefault(name, child) | ||
| if existing is not child: | ||
| # Its children's names start with the clashing name, so skip | ||
| # them too | ||
| LOGGER.warning( | ||
| "Not registering %s or its children, name '%s' is in use", | ||
| child, | ||
| name, | ||
| ) | ||
| continue | ||
| self._register_children(child, ancestor_names) | ||
|
|
||
| def unregister_all_devices(self): | ||
| """Unregister all devices from the context.""" | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are duplicate devices overwritten here but not below (389..397)?