From d7b2684879ad3ff4735295102f3fe3b505d4c7e9 Mon Sep 17 00:00:00 2001 From: Gary Yendell Date: Mon, 10 Nov 2025 13:49:41 +0000 Subject: [PATCH] Fix EpicsCATransport to pass length with initial_value for string records softioc sets the length of the initial value as the max length, so it can never be set if it is empty initially. Override with the driver set length or 256 by default. --- src/fastcs/datatypes.py | 3 +++ src/fastcs/transport/epics/ca/util.py | 8 +++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/fastcs/datatypes.py b/src/fastcs/datatypes.py index d152adba..7d4124a4 100644 --- a/src/fastcs/datatypes.py +++ b/src/fastcs/datatypes.py @@ -128,6 +128,9 @@ def initial_value(self) -> bool: class String(DataType[str]): """`DataType` mapping to builtin ``str``.""" + length: int | None = None + """Maximum length of string to display in transports""" + @property def dtype(self) -> type[str]: return str diff --git a/src/fastcs/transport/epics/ca/util.py b/src/fastcs/transport/epics/ca/util.py index 4cdd182a..29dfee28 100644 --- a/src/fastcs/transport/epics/ca/util.py +++ b/src/fastcs/transport/epics/ca/util.py @@ -32,7 +32,7 @@ EPICS_ALLOWED_DATATYPES = (Bool, DataType, Enum, Float, Int, String, Waveform) -EPICS_WAVEFORM_LENGTH = 256 +DEFAULT_STRING_WAVEFORM_LENGTH = 256 DATATYPE_FIELD_TO_RECORD_FIELD = { "prec": "PREC", @@ -79,6 +79,8 @@ def record_metadata_from_datatype( arguments.pop("DRVH", None) match datatype: + case String(): + arguments["length"] = datatype.length or DEFAULT_STRING_WAVEFORM_LENGTH case Waveform(): if len(datatype.shape) != 1: raise TypeError( @@ -138,8 +140,8 @@ def cast_to_epics_type(datatype: DataType[T], value: T) -> Any: return datatype.index_of(datatype.validate(value)) else: # enum backed by string record return datatype.validate(value).name - case String(): - return value[: EPICS_WAVEFORM_LENGTH - 1] + case String() as string: + return value[: string.length] case datatype if issubclass(type(datatype), EPICS_ALLOWED_DATATYPES): return value case _: