I am porting some logic from GDA. It is a device that can be configured with channels and then give those channels names when being read.
class MyDevice(StandardReadable):
def __init__(self, prefix: str, name: str = ""):
with self.add_children_as_readables():
self.hm3amp20 = epics_signal_r(float, prefix + f".S{2}")
self.sm5amp8 = epics_signal_r(float, prefix + f".S{3}")
self.smpmamp39 = epics_signal_r(float, prefix + f".S{4}")
self.rfdamp10 = epics_signal_r(float, prefix + f".S{5}")
super().__init__(name)
So this translated to the above, however this has hardcoded the channels. I wanted to use the device vector for this instead and have it be configurable:
class MyDevice(StandardReadable):
def __init__(self, prefix: str, config: dict[int, str], name: str = ""):
with self.add_children_as_readables():
self.channels = DeviceVector(
{
key: epics_signal_r(float, prefix + f".S{key}", name=value)
for key, value in config.items()
}
)
super().__init__(name)
@pytest.fixture
def my_device() -> MyDevice:
with init_devices(mock=True):
my_device = MyDevice(
"TEST:", {2: "hm3amp20", 3: "sm5amp8", 4: "smpmamp39", 5: "rfdamp10"}
)
return my_device
However, the read outputs is this:
{
"my_device-channels-2": partial_reading(0),
"my_device-channels-3": partial_reading(0),
"my_device-channels-4": partial_reading(0),
"my_device-channels-5": partial_reading(0),
}
rather than
{
"my_device-channels-hm3amp20": partial_reading(0),
"my_device-channels-sm5amp8": partial_reading(0),
"my_device-channels-smpmamp39": partial_reading(0),
"my_device-channels-rfdamp10": partial_reading(0),
},
So the name that I provided to the signal was ignored and overwritten by key value int instead. I think we should be able to customise the signals name so that the read outputs the desired users format. We can do this very easily by adding this small change to DeviceVector
from this
def children(self) -> Iterator[tuple[str, Device]]:
for key, child in self._children.items():
yield str(key), child
yield from super().children()
to this
def children(self) -> Iterator[tuple[str, Device]]:
for key, child in self._children.items():
name = str(key) if child.name == "" else child.name
yield name, child
yield from super().children()
This way, we can still access the signals via my_device.channels[x] but the read is the desired output.
I am porting some logic from GDA. It is a device that can be configured with channels and then give those channels names when being read.
So this translated to the above, however this has hardcoded the channels. I wanted to use the device vector for this instead and have it be configurable:
However, the read outputs is this:
{ "my_device-channels-2": partial_reading(0), "my_device-channels-3": partial_reading(0), "my_device-channels-4": partial_reading(0), "my_device-channels-5": partial_reading(0), }rather than
{ "my_device-channels-hm3amp20": partial_reading(0), "my_device-channels-sm5amp8": partial_reading(0), "my_device-channels-smpmamp39": partial_reading(0), "my_device-channels-rfdamp10": partial_reading(0), },So the name that I provided to the signal was ignored and overwritten by key value int instead. I think we should be able to customise the signals name so that the read outputs the desired users format. We can do this very easily by adding this small change to
DeviceVectorfrom this
to this
This way, we can still access the signals via
my_device.channels[x]but the read is the desired output.