Skip to content

Commit

Permalink
Fix autosave loop logic, allow autosave to be set after pv init but b…
Browse files Browse the repository at this point in the history
…efore LoadDatabase

set autosave attribute in ProcessDeviceSupportCore init
  • Loading branch information
jsouter committed Jul 4, 2024
1 parent c6b90b4 commit 8c9c5af
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 19 deletions.
36 changes: 20 additions & 16 deletions softioc/autosave.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,23 @@ def configure(directory=None, save_period=None, device=None):
else:
Autosave.directory = Path(directory)

def set_autosave(pv, value=True):
if value:
Autosave.add_pv(pv)
else:
Autosave.remove_pv(pv)


class Autosave:
_instance = None
_pvs = {}
save_period = 30.0
device_name = None
directory = None
enabled = True
backup_on_restart = True

def __init__(
self,
):
def __init__(self):
if not self.directory:
raise RuntimeError(
"Autosave directory is not known, call "
Expand Down Expand Up @@ -80,13 +85,15 @@ def backup_sav_file(self):
if sav_path.is_file():
shutil.copy2(sav_path, self._get_timestamped_backup_sav_path())

def add_pv(self, pv):
pv.autosave = True
self._pvs[pv.name] = pv
@classmethod
def add_pv(cls, pv):
pv.set_autosave(True)
cls._pvs[pv.name] = pv

def remove_pv(self, pv):
pv.autosave = False
self._pvs.pop(pv.name, None)
@classmethod
def remove_pv(cls, pv):
pv.set_autosave(False)
cls._pvs.pop(pv.name, None)

def _get_timestamped_backup_sav_path(self):
sav_path = self._get_current_sav_path()
Expand Down Expand Up @@ -145,11 +152,8 @@ def loop(self):
if not self._pvs:
return # end thread if no PVs to save
while True:
try:
self._stop_event.wait(timeout=self.save_period)
except TimeoutError:
# No stop requested, we should save and continue
self.save()
else:
# Stop requested
self._stop_event.wait(timeout=self.save_period)
if self._stop_event.is_set(): # Stop requested
return
else: # No stop requested, we should save and continue
self.save()
10 changes: 7 additions & 3 deletions softioc/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,13 @@ class ProcessDeviceSupportCore(DeviceSupportCore, RecordLookup):
# from record init or processing
_epics_rc_ = EPICS_OK

# all record types can support autosave
def __init__(self, name, **kargs):
self.autosave = kargs.pop("autosave", False)
self.__super.__init__(name, **kargs)

def set_autosave(self, value):
self.autosave = value

# Most subclasses (all except waveforms) define a ctypes constructor for the
# underlying EPICS compatible value.
Expand Down Expand Up @@ -109,7 +116,6 @@ class ProcessDeviceSupportIn(ProcessDeviceSupportCore):
_link_ = 'INP'

def __init__(self, name, **kargs):
self.autosave = kargs.pop("autosave", False)
if 'initial_value' in kargs:
value = self._value_to_epics(kargs.pop('initial_value'))
else:
Expand Down Expand Up @@ -160,7 +166,6 @@ class ProcessDeviceSupportOut(ProcessDeviceSupportCore):
_link_ = 'OUT'

def __init__(self, name, **kargs):
self.autosave = kargs.pop('autosave', False)
on_update = kargs.pop('on_update', None)
on_update_name = kargs.pop('on_update_name', None)
# At most one of on_update and on_update_name can be specified
Expand Down Expand Up @@ -434,7 +439,6 @@ class WaveformBase(ProcessDeviceSupportCore):


def __init__(self, name, _wf_nelm, _wf_dtype, **kargs):
self.autosave = kargs.pop("autosave", False)
self._dtype = _wf_dtype
self._nelm = _wf_nelm
self.__super.__init__(name, **kargs)
Expand Down

0 comments on commit 8c9c5af

Please sign in to comment.