Skip to content

Commit

Permalink
Merge pull request #1034 from BCDA-APS/1022-subscription-with-fake
Browse files Browse the repository at this point in the history
only subscribe with event_type="setpoint" when it is available
  • Loading branch information
prjemian authored Nov 20, 2024
2 parents 105416f + 4062a42 commit e9780ed
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 2 deletions.
6 changes: 6 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ describe future plans.

- Add 'dynamic_import()' (support 'ad_creator()' from device file).

Fixes
-----

- 'PVPositionerSoftDone' used an invalid subscription event type
in unusual cases (with fake ophyd simulated devices).

Maintenance
-----------

Expand Down
5 changes: 4 additions & 1 deletion apstools/devices/positioner_soft_done.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,10 @@ def __init__(

self.readback.subscribe(self.cb_readback)
self.setpoint.subscribe(self.cb_setpoint)
self.setpoint.subscribe(self.cb_update_target, event_type="setpoint")
options = {}
if "setpoint" in self.event_types:
options["event_type"] = "setpoint"
self.setpoint.subscribe(self.cb_update_target, **options)

# cancel subscriptions before object is garbage collected
weakref.finalize(self.readback, self.readback.unsubscribe_all)
Expand Down
20 changes: 19 additions & 1 deletion apstools/devices/tests/test_positioner_soft_done.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import math
import time
from contextlib import nullcontext as does_not_raise

import pytest
from ophyd import Component
from ophyd import EpicsSignal
from ophyd.sim import instantiate_fake_device

from ...synApps.swait import UserCalcsDevice
from ...tests import IOC_GP
from ...tests import common_attribute_quantities_test
from ...tests import rand
from ...tests import timed_pause
from ...utils import run_in_thread
from ..positioner_soft_done import TARGET_UNDEFINED
from ..positioner_soft_done import PVPositionerSoftDone
from ..positioner_soft_done import PVPositionerSoftDoneWithStop
from ..positioner_soft_done import TARGET_UNDEFINED

PV_PREFIX = f"{IOC_GP}gp:"
delay_active = False
Expand Down Expand Up @@ -365,3 +367,19 @@ def motion(p, goal):
motion(calcpos, round(rand(-1.1, 0.2), 4)) # known starting position
motion(calcpos, target)
motion(calcpos, target) # issue #725, repeated move to same target


def test_issue_1022():
"""
PVPositionerSoftDone should work with simulated fake devices.
'instantiate_fake_device()' produces a device that does not
have the 'setpoint' event_type.
"""
with does_not_raise():
d = instantiate_fake_device(
PVPositionerSoftDone,
readback_pv="spam:",
setpoint_pv="eggs:",
)
assert d is not None

0 comments on commit e9780ed

Please sign in to comment.