Skip to content

Commit

Permalink
Allow precision 0 float records to be represented as int signals (#509)
Browse files Browse the repository at this point in the history
* Allow precision 0 float records to be represented as int signals
  • Loading branch information
olliesilvester authored Aug 13, 2024
1 parent e4fb849 commit d5da999
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 12 deletions.
13 changes: 10 additions & 3 deletions src/ophyd_async/epics/signal/_aioca.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,17 @@ def make_converter(
value = list(values.values())[0]
# Done the dbr check, so enough to check one of the values
if datatype and not isinstance(value, datatype):
raise TypeError(
f"{pv} has type {type(value).__name__.replace('ca_', '')} "
+ f"not {datatype.__name__}"
# Allow int signals to represent float records when prec is 0
is_prec_zero_float = (
isinstance(value, float)
and get_unique({k: v.precision for k, v in values.items()}, "precision")
== 0
)
if not (datatype is int and is_prec_zero_float):
raise TypeError(
f"{pv} has type {type(value).__name__.replace('ca_', '')} "
+ f"not {datatype.__name__}"
)
return CaConverter(pv_dbr, None)


Expand Down
19 changes: 11 additions & 8 deletions src/ophyd_async/epics/signal/_p4p.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,14 +335,17 @@ def make_converter(datatype: Optional[Type], values: Dict[str, Any]) -> PvaConve
return PvaEnumConverter(
get_supported_values(pv, datatype, datatype.choices)
)
elif (
datatype
and not issubclass(typ, datatype)
and not (
typ is float and datatype is int
) # Allow float -> int since prec can be 0
):
raise TypeError(f"{pv} has type {typ.__name__} not {datatype.__name__}")
elif datatype and not issubclass(typ, datatype):
# Allow int signals to represent float records when prec is 0
is_prec_zero_float = typ is float and (
get_unique(
{k: v["display"]["precision"] for k, v in values.items()},
"precision",
)
== 0
)
if not (datatype is int and is_prec_zero_float):
raise TypeError(f"{pv} has type {typ.__name__} not {datatype.__name__}")
return PvaConverter()
elif "NTTable" in typeid:
return PvaTableConverter()
Expand Down
5 changes: 4 additions & 1 deletion tests/core/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,10 @@ async def test_error_handling_connection_timeout(caplog):
assert str(e.value) == str(ONE_WORKING_ONE_TIMEOUT_OUTPUT)

logs = caplog.get_records("call")
assert len(logs) == 3

# See https://github.com/bluesky/ophyd-async/issues/519
# assert len(logs) == 3

assert "signal ca://A_NON_EXISTENT_SIGNAL timed out" == logs[-1].message
assert logs[-1].levelname == "DEBUG"

Expand Down
14 changes: 14 additions & 0 deletions tests/epics/signal/test_records.db
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,20 @@ record(ao, "$(P)float") {
field(PINI, "YES")
}

record(ao, "$(P)float_prec_0") {
field(PREC, "0")
field(EGU, "mm")
field(VAL, "3")
field(PINI, "YES")
}

record(ao, "$(P)float_prec_1") {
field(PREC, "1")
field(EGU, "mm")
field(VAL, "3")
field(PINI, "YES")
}

record(stringout, "$(P)str") {
field(VAL, "hello")
field(PINI, "YES")
Expand Down
15 changes: 15 additions & 0 deletions tests/epics/signal/test_signals.py
Original file line number Diff line number Diff line change
Expand Up @@ -886,3 +886,18 @@ async def test_signal_not_return_no_limits(ioc: IOC):
await sig.connect()
datakey = (await sig.describe())[""]
assert not hasattr(datakey, "limits")


async def test_signals_created_for_prec_0_float_can_use_int(ioc: IOC):
pv_name = f"{ioc.protocol}://{PV_PREFIX}:{ioc.protocol}:float_prec_0"
sig = epics_signal_rw(int, pv_name)
await sig.connect()


async def test_signals_created_for_not_prec_0_float_cannot_use_int(ioc: IOC):
pv_name = f"{ioc.protocol}://{PV_PREFIX}:{ioc.protocol}:float_prec_1"
sig = epics_signal_rw(int, pv_name)
with pytest.raises(
TypeError, match=f"{ioc.protocol}:float_prec_1 has type float not int"
):
await sig.connect()

0 comments on commit d5da999

Please sign in to comment.