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
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
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