-
Notifications
You must be signed in to change notification settings - Fork 5
Implement SubControllerVector #192
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
7f0d4b7
7591e8f
d6bfed5
98fdd76
57b411d
d520bbe
016344f
de036d7
c8a6c0a
480bab8
d882765
f76fa52
3e8e43a
a8805b9
09c9842
c696a97
b27499b
ecaf5ec
cad6c34
c231cd9
62f3761
c443171
a7fd462
a339629
edad64f
249128a
06505fd
4b3e2e3
b0056c7
8fb3065
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 |
|---|---|---|
|
|
@@ -92,6 +92,9 @@ def _verify_in_datatype(_, value): | |
| return value in datatype.names | ||
|
|
||
| arguments["validate"] = _verify_in_datatype | ||
| case Bool(): | ||
| arguments["ZNAM"] = "False" | ||
| arguments["ONAM"] = "True" | ||
|
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. This seems unrelated?
Contributor
Author
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. I'm actually not sure how this got here; looks like you committed these in this ref? Not sure if this relates to another ticket?
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. Ah right yes and I couldn't rebase it away because there is a merge from main after it. If we merge that change first and then squash merge this it should be fine
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. Made #261 to resolve this |
||
|
|
||
| return arguments | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,119 @@ | ||
| from collections import defaultdict | ||
| from typing import Literal | ||
|
|
||
| from p4p import Type, Value | ||
| from p4p.nt.common import alarm, timeStamp | ||
| from p4p.server import StaticProvider | ||
| from p4p.server.asyncio import SharedPV | ||
|
|
||
| from fastcs.attributes import Attribute, AttrR, AttrRW, AttrW | ||
| from fastcs.controller_api import ControllerAPI | ||
| from fastcs.util import snake_to_pascal | ||
|
|
||
| from .types import p4p_alarm_states, p4p_timestamp_now | ||
|
|
||
| AccessModeType = Literal["r", "w", "rw", "d", "x"] | ||
|
|
||
|
|
||
| # TODO: This should be removed after https://github.com/DiamondLightSource/FastCS/issues/260 | ||
| def _attribute_to_access(attribute: Attribute) -> AccessModeType: | ||
GDYendell marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| match attribute: | ||
| case AttrRW(): | ||
| return "rw" | ||
| case AttrR(): | ||
| return "r" | ||
| case AttrW(): | ||
| return "w" | ||
| case _: | ||
| raise ValueError(f"Unknown attribute type {type(attribute)}") | ||
|
|
||
|
|
||
| def add_pvi_info( | ||
| provider: StaticProvider, | ||
| pv_prefix: str, | ||
| controller_api: ControllerAPI, | ||
| description: str | None = None, | ||
| ) -> StaticProvider: | ||
| """Add PVI information to given provider.""" | ||
| provider.add( | ||
| f"{pv_prefix}:PVI", | ||
| SharedPV(initial=_make_p4p_value(pv_prefix, controller_api, description)), | ||
| ) | ||
| return provider | ||
|
|
||
|
|
||
| def _make_p4p_value( | ||
| pv_prefix: str, controller_api: ControllerAPI, description: str | None | ||
| ) -> Value: | ||
| display = ( | ||
| {"display": {"description": description}} if description is not None else {} | ||
| ) # Defined here so the value can be (none) | ||
|
|
||
| raw_value = _make_p4p_raw_value(pv_prefix, controller_api) | ||
| p4p_type = _make_type_for_raw_value(raw_value) | ||
|
|
||
| try: | ||
| return Value( | ||
| p4p_type, | ||
| { | ||
| **p4p_alarm_states(), | ||
| **p4p_timestamp_now(), | ||
| **display, | ||
| "value": raw_value, | ||
| }, | ||
| ) | ||
| except KeyError as e: | ||
| raise ValueError(f"Failed to create p4p Value from {raw_value}") from e | ||
|
|
||
|
|
||
| def _make_p4p_raw_value(pv_prefix: str, controller_api: ControllerAPI) -> dict: | ||
| p4p_raw_value = defaultdict(dict) | ||
| # Sub-controller api returned if current item is a Controller | ||
| for pv_leaf, sub_controller_api in controller_api.sub_apis.items(): | ||
| # Add Controller entry | ||
| pv = f"{pv_prefix}:{snake_to_pascal(pv_leaf)}:PVI" | ||
| if sub_controller_api.path[-1].isdigit(): | ||
| # Sub-device of a ControllerVector | ||
| p4p_raw_value[f"__{int(pv_leaf)}"]["d"] = pv | ||
| else: | ||
| p4p_raw_value[pv_leaf]["d"] = pv | ||
| for pv_leaf, attribute in controller_api.attributes.items(): | ||
| # Add attribute entry | ||
| pv = f"{pv_prefix}:{snake_to_pascal(pv_leaf)}" | ||
| p4p_raw_value[pv_leaf][_attribute_to_access(attribute)] = pv | ||
| for pv_leaf, _ in controller_api.command_methods.items(): | ||
| pv = f"{pv_prefix}:{snake_to_pascal(pv_leaf)}" | ||
| p4p_raw_value[pv_leaf]["x"] = pv | ||
|
|
||
| return p4p_raw_value | ||
|
|
||
|
|
||
| def _make_type_for_raw_value(raw_value: dict) -> Type: | ||
| p4p_raw_type = [] | ||
| for pvi_group_name, access_to_field in raw_value.items(): | ||
| pvi_group_structure = [] | ||
| for access, field in access_to_field.items(): | ||
| if isinstance(field, str): | ||
| pvi_group_structure.append((access, "s")) | ||
| elif isinstance(field, dict): | ||
| pvi_group_structure.append( | ||
| ( | ||
| access, | ||
| ( | ||
| "S", | ||
| None, | ||
| [(v, "s") for v, _ in field.items()], | ||
| ), | ||
| ) | ||
| ) | ||
|
|
||
| p4p_raw_type.append((pvi_group_name, ("S", "structure", pvi_group_structure))) | ||
|
|
||
| return Type( | ||
| [ | ||
| ("alarm", alarm), | ||
| ("timeStamp", timeStamp), | ||
| ("display", ("S", None, [("description", "s")])), | ||
| ("value", ("S", "structure", p4p_raw_type)), | ||
| ] | ||
| ) | ||
Uh oh!
There was an error while loading. Please reload this page.