示例#1
0
async def caget(pv: str, datatype=None, format=dbr.FORMAT_RAW, count=0):
    """Retrieves an `AugmentedValue` from one or more PVs.

    Args:
        datatype: Override `Datatype` to a non-native type
        format: Request extra `Format` fields
        count: Request a specific element `Count` in an array
        timeout: After how long should caget `Timeout`
        throw: If False then return `CANothing` instead of raising an exception

    Returns:
        `AugmentedValue` for single PV or [`AugmentedValue`] for a list of PVs
    """
    # Note: docstring refers to both this function and caget_array below
    # Retrieve the requested channel and ensure it's connected.
    channel = get_channel(pv)
    await channel.wait()

    # A count of zero will be treated by EPICS in a version dependent manner,
    # either returning the entire waveform (equivalent to count=-1) or a data
    # dependent waveform length.
    if count < 0:
        # Treat negative count request as request for fixed underlying channel
        # size.
        count = cadef.ca_element_count(channel)
    elif count > 0:
        # Need to ensure we don't ask for more than the channel can provide as
        # otherwise may get API error.
        count = min(count, cadef.ca_element_count(channel))

    # Assemble the callback context.  Note that we need to explicitly
    # increment the reference count so that the context survives until the
    # callback routine gets to see it.
    dbrcode, dbr_to_value = dbr.type_to_dbr(channel, datatype, format)
    done = ValueEvent[AugmentedValue]()
    loop = asyncio.get_event_loop()
    context = (pv, dbr_to_value, done, loop)
    ctypes.pythonapi.Py_IncRef(context)

    # Perform the actual put as a non-blocking operation: we wait to be
    # informed of completion, or time out.
    cadef.ca_array_get_callback(dbrcode, count, channel, _caget_event_handler,
                                ctypes.py_object(context))
    _flush_io()
    result = await done.wait()
    return result
示例#2
0
    async def __create_subscription(self, events, datatype, format, count,
                                    connect_timeout):
        """Creates the channel subscription with the specified parameters:
        event mask, datatype and format, array count.  Waits for the channel
        to become connected."""

        # Need to first wait for the channel to connect before we can do
        # anything else. This will either succeed, or wait forever, raising
        # if close() is called
        await self.__wait_for_channel(connect_timeout)

        self.state = self.OPEN

        # Treat a negative count as a request for the complete data
        if count < 0:
            count = cadef.ca_element_count(self.channel)

        # Connect to the channel to be kept informed of connection updates.
        self.channel._add_subscription(self)
        # Convert the datatype request into the subscription datatype.
        dbrcode, self.dbr_to_value = dbr.type_to_dbr(self.channel, datatype,
                                                     format)

        # Finally create the subscription with all the requested properties
        # and hang onto the returned event id as our implicit ctypes
        # parameter.
        event_id = ctypes.c_void_p()
        cadef.ca_create_subscription(
            dbrcode,
            count,
            self.channel,
            events,
            self.__on_event,
            ctypes.py_object(self),
            ctypes.byref(event_id),
        )
        _flush_io()
        self._as_parameter_ = event_id.value
示例#3
0
 def __init__(self, pv: str, channel: Channel):
     #: True iff the channel was successfully connected
     self.ok: bool = True
     #: The name of the PV
     self.name: str = pv
     #: State of channel as an integer. Look up ``state_strings[state]``
     #: for textual description.
     self.state: int = cadef.ca_state(channel)
     #: Host name and port of server providing this PV
     self.host: str = cadef.ca_host_name(channel)
     #: True iff read access to this PV
     self.read: bool = cadef.ca_read_access(channel)
     #: True iff write access to this PV
     self.write: bool = cadef.ca_write_access(channel)
     if self.state == cadef.cs_conn:
         #: Data count of this channel
         self.count: int = cadef.ca_element_count(channel)
         #: Underlying channel datatype as `Dbr` value. Look up
         #: ``datatype_strings[datatype]`` for textual description.
         self.datatype: int = cadef.ca_field_type(channel)
     else:
         self.count = 0
         self.datatype = 7  # DBF_NO_ACCESS