Beispiel #1
0
    def add_callback(self,
                     callback,
                     *,
                     index=None,
                     run_now=False,
                     with_ctrlvars=True,
                     **kw):
        """add a callback to a PV.  Optional keyword arguments
        set here will be preserved and passed on to the callback
        at runtime.

        Note that a PV may have multiple callbacks, so that each
        has a unique index (small integer) that is returned by
        add_callback.  This index is needed to remove a callback."""
        if not callable(callback):
            raise CaprotoValueError()
        if index is not None:
            raise CaprotoValueError("why do this")
        index = next(self._cb_count)
        self.callbacks[index] = (callback, kw)

        if self.connected:
            self._check_auto_monitor_sub()

        if with_ctrlvars and self.connected:
            self.get_ctrlvars()
        if run_now:
            self.get(as_string=True)
            if self.connected:
                self.run_callback(index)
        return index
Beispiel #2
0
def _pyepics_get_value(value, string_value, full_type, native_count, *,
                       requested_count, enum_strings, as_string, as_numpy):
    'Handle all the fun pyepics get() kwargs'
    if (as_string and (full_type in ca.char_types)
            or full_type in ca.string_types):
        return string_value
    if as_string and full_type in ca.enum_types:
        if enum_strings is None:
            raise CaprotoValueError('Enum strings unset')
        ret = []
        for r in value:
            try:
                ret.append(enum_strings[r])
            except IndexError:
                ret.append('')
        if len(ret) == 1:
            ret, = ret
        return ret

    elif native_count == 1 and len(value) == 1:
        if requested_count is None:
            return value.tolist()[0]
        else:
            return value

    elif not as_numpy:
        return value.tolist()

    return value
Beispiel #3
0
def caput_many(pvlist,
               values,
               wait=False,
               connection_timeout=None,
               put_timeout=60):
    """put values to a list of PVs, as fast as possible

    This does not maintain the PV objects it makes.

    If wait is 'each', *each* put operation will block until
    it is complete or until the put_timeout duration expires.

    If wait is 'all', this method will block until *all*
    put operations are complete, or until the put_timeout
    duration expires.

    Note that the behavior of 'wait' only applies to the
    put timeout, not the connection timeout.

    Returns a list of integers for each PV, 1 if the put
    was successful, or a negative number if the timeout
    was exceeded.
    """
    if len(pvlist) != len(values):
        raise CaprotoValueError(
            "List of PV names must be equal to list of values.")

    # context = PV._default_context
    # TODO: context.get_pvs(...)

    out = []
    pvs = [
        PV(name, auto_monitor=False, connection_timeout=connection_timeout)
        for name in pvlist
    ]

    wait_all = (wait == 'all')
    wait_each = (wait == 'each')
    for p, v in zip(pvs, values):
        try:
            p.wait_for_connection(connection_timeout)
            p.put(v,
                  wait=wait_each,
                  timeout=put_timeout,
                  use_complete=wait_all)
        except TimeoutError:
            out.append(-1)
        else:
            out.append(1)

    if not wait_all:
        return [o if o == 1 else -1 for o in out]

    start_time = time.time()
    while not all([(p.connected and p.put_complete) for p in pvs]):
        elapsed_time = time.time() - start_time
        if elapsed_time > put_timeout:
            break
    return [1 if (p.connected and p.put_complete) else -1 for p in pvs]
Beispiel #4
0
    def put(self,
            value,
            *,
            wait=False,
            timeout=30.0,
            use_complete=False,
            callback=None,
            callback_data=None):
        """set value for PV, optionally waiting until the processing is
        complete, and optionally specifying a callback function to be run
        when the processing is complete.
        """
        if callback_data is None:
            callback_data = ()
        if not self._args['write_access']:
            raise AccessRightsException(
                'Cannot put to PV according to write access')

        if self._args['typefull'] in ca.enum_types:
            if isinstance(value, str):
                try:
                    value = self.enum_strs.index(value)
                except ValueError:
                    raise CaprotoValueError('{} is not in Enum ({}'.format(
                        value, self.enum_strs))

        if isinstance(value, str):
            if self.typefull in ca.char_types:
                # have to add a null-terminator char
                value = value.encode(STR_ENC) + b'\0'
            else:
                value = (value, )
        elif not isinstance(value, Iterable):
            value = (value, )

        if len(value) and isinstance(value[0], str):
            value = tuple(v.encode(STR_ENC) for v in value)

        notify = any((use_complete, callback is not None, wait))

        if callback is None and not use_complete:
            run_callback = None
        else:

            def run_callback(cmd):
                if use_complete:
                    self._args['put_complete'] = True
                if callback is not None:
                    callback(*callback_data)

        # So, in pyepics, put_complete strictly refers to the functionality
        # where we toggle 'put_complete' in the args after a
        # WriteNotifyResponse.
        if notify:
            if use_complete:
                self._args['put_complete'] = False
        else:
            wait = False

        self._caproto_pv.write(value,
                               wait=wait,
                               callback=run_callback,
                               timeout=timeout,
                               notify=notify)