Object-oriented KTL Python¶
The object-oriented approach in KTL Python can greatly simplify a client application’s overall use of the module. When using the procedural approach, values must be cached, callbacks are more complicated to establish, and a lot of client-side metadata must be stored to correctly handle exceptional circumstances, such as an inability to monitor a given KTL keyword.
The Service
and Keyword
classes address these repetitive
needs internally as much as possible in order to streamline the use of
KTL Python.
Service
objects¶
-
class
ktl.
Service
(name, populate=False)¶ A complete representation of a single KTL service. name is a case-sensitive string representing the KTL service name. If populate is set to True, the Service instance will immediately instantiate all
Keyword
instances as part of its initialization. The default behavior is to do just-in-time instantiation ofKeyword
instances.When accessing
Keyword
instances within aService
instance, theService
can be treated like a dictionary. See the basic use section of the Example usage document.-
has_key
(keyword)¶ Alias for
Service.has_keyword()
.
-
heartbeat
(keyword, period=5)¶ Identify keyword (either a keyword name, or a
Keyword
instance) as a heartbeat keyword for this Service. A heartbeat keyword should broadcast regularly to indicate that the KTL service is functional. period should be set to the maximum expected interval (in seconds) between heartbeat broadcasts.All hearbeats are monitored by a background
FirstResponder
thread that wakes up according to the most imminent expiration of any heartbeat’s set period. If the heartbeat does not update within period seconds, an external check will be made to see whether the service is responding. If it is, and local broadcasts have not resumed, allService
instances corresponding to the affected KTL service will be resuscitated. See theFirstResponder
class andParamedic.resuscitate()
for details.Multiple heartbeats may be specified for a single
Service
instance. This is desirable if distinct dispatchers provide subsets of the keywords within a single KTL service. The failure of any heartbeat will trigger a full resuscitate operation; no attempt is made to distinguish betweenKeyword
instances serviced by distinct dispatchers.
-
keywords
()¶ List all keywords available in this Service instance.
-
list
()¶ Alias for
Service.keywords()
.
-
monitor
(start=True, prime=True, wait=True)¶ Start or stop monitoring of all
Keyword
instances within this Service. A typical client application is only interested in monitoring a subset of the available keywords; in that case, useKeyword.monitor()
instead. Refer toKeyword.monitor()
for a description of the parameters.
-
populated
()¶ Returns a list of all keywords (as keyword names) that are instantiated as
Keyword
instances within this Service instance. AKeyword
instance is not created until it is used by the client application.
-
read
(keyword, binary=False, both=False, wait=True, timeout=None)¶ Perform a
ktl_read()
operation and return the most current value for the designated keyword. Refer toKeyword.read()
for a description of the other arguments.
-
subscribe
(start=True, prime=True)¶ Alias for
Service.monitor()
.
-
wait
(timeout=None, keywords=None, expression=None, reset=False, action=None, case=False)¶ Wait for any monitored
Keyword
instance in thisService
to receive a new value. If expression is set,Service.wait()
effectively acts as a wrapper toService.waitFor()
. If keywords is set to an iterable list of keywords (specified as either strings orKeyword
instances),Service.wait()
will act as if a parallel series ofKeyword.wait()
calls were invoked, with the first broadcast activity releasingService.wait()
. If reset is set to True, the notification flag will be cleared before waiting against it– this is dangerous, as this introduces a race condition between the arrival of the event itself, and the invocation ofService.wait()
. If the event occurs first, the caller may wind up waiting indefinitely. If timeout (in whole or partial seconds) is set,Service.wait()
will return False if no update occurs before the timeout expires. Otherwise,Service.wait()
returns True to indicate that the wait completed successfully.
-
waitFor
(expression, timeout=None, case=False)¶ Thin wrapper to
waitfor()
, using thisService
instance as the default service.
-
waitfor
(expression, timeout=None)¶ Alias for
Service.waitFor()
.
-
write
(keyword, value, wait=True, binary=False, timeout=None)¶ Perform a
ktl_write()
operation to assign the designated value to the designated keyword. Refer toKeyword.write()
for a description of the other parameters.
-
Keyword
objects¶
-
class
ktl.
Keyword
(service, name, ktlc_instance)¶ A complete representation of a KTL keyword. It is not expected that users will instantiate Keyword instances directly: Keyword instances should always be acquired from a
Service
instance.See also the basic use section of the Example usage document.
Keyword
instances can be used with all boolean, comparison, and arithmetic operations. The support for these operations has its caveats. For all such operations, theKeyword
instance must have a value, either via aKeyword.read()
call, or by enabling asynchronous updates viaKeyword.monitor()
. Note that in-place operations (+=
,-=
, etc.) will automatically invokeKeyword.monitor()
if necessary. In-place operations also imply a blocking invocation ofKeyword.write()
. In order to support the use ofKeyword
instances as dictionary keys, comparison operations between twoKeyword
instances do not compare the values of the two keywords, such operations compare their names. TheExpression
class goes to some length to manage comparisons between twoKeyword
instances to defeat this behavior. Comparisons betweenKeyword
instances and all other data types are intended to match the behavior of comparisons between standard Python types; for example, a booleanKeyword
can meaningfully be compared against the integers 0 and 1, just like the standard Python bool type.In addition its member functions, a
Keyword
also provides significant functionality via dictionary-like keys. Many of these keys trigger just-in-time acquisition of data, caching the result for future use. The following keys are supported:Key Operation performed ascii or asc Return the current ascii representation of the Keyword
; if theKeyword
has no value, aKeyword.read()
operation will be performed. Will raise an exception if one is active for thisKeyword
instance.binary or bin Same as ascii, but will return the binary representation. broadcasts Return a boolean indicating whether this KTL keyword supports broadcasts. dictionary or dict Same as ascii, but will return a dictionary representation of the current value, if and only if the KTL keyword is a numeric array type. enumerators or enum For enumerated KTL keyword types (including booleans), return a tuple containing the enumerators for all available named positions. error Return a string representation of the active exception associated with this Keyword
, if any. The exception object itself is stored asKeyword.error
.history Return a tuple containing a small chronological set of the most recent HistorySlice
instances for thisKeyword
. The most recent broadcast is at the end of the sequence.keys For numeric KTL array types, return a tuple containing the key name for each individual array value. name Return the name of the keyword. All keyword names are case-insensitive, and are handled internally in all upper-case. monitor or monitored Return a boolean indicating whether this Keyword
instance is currently subscribed to broadcasts.notify_reads Return a boolean indicating whether this KTL keyword supports KTL_NOTIFY read operations. notify_writes Return a boolean indicating whether this KTL keyword supports KTL_NOTIFY write operations. populated Return a boolean indicating whether this Keyword
instance has a value, either from an explicitKeyword.read()
operation or from a broadcast.range Return a dictionary containing the minimum and maximum values for this KTL keyword. If no range is set, return None. If either the minimum or maximum is not set, that specific value will be set to None. These values are expected to be the binary representation; a a nested ‘ascii’ dictionary will contain the same numeric values put through the keyword’s binary-to-ascii routine. For most keywords, there is no significant distinction between the two. reads Return a boolean indicating whether this KTL keyword supports read operations. servers Return a tuple containing the server names associated with this KTL keyword. timestamp Return the floating point timestamp (in UNIX seconds) associated with the most recent update to the value of the Keyword
. It is recommended that you work instead with theHistorySlice
instances provided by the history key.type Return the KTL type of this KTL keyword as a string. Use the top-level KTL_DATATYPE
dictionary to map between string and integer representations of the KTL type.units Return the ‘units’ associated with this KTL keyword, if any. writes Return a boolean indicating whether this KTL keyword supports write operations. a
Keyword
defines the following functions:-
callback
(function, remove=False, preferred=False)¶ Request that a callback function be invoked whenever a KTL broadcast is received for this keyword. The callback function should accept as its sole argument a Keyword instance. If remove is set to False, the designated function will be removed from the set of active callbacks. If preferred is set to True, this callback will be remembered as a preferred callback, which gets invoked before all other non-preferred callbacks.
Keyword.callback()
is typically used in conjunction withKeyword.monitor()
, orKeyword.poll()
if the specific KTL keyword does not support broadcasts.
-
cast
(value)¶ Cast the provided value to a native Python type appropriate for this keyword. For example, a numeric keyword type would cast the string ‘1.2’ to a floating point number; an integer keyword type would convert the same string to the number 1.
-
clone
()¶ Return a copy of this
Keyword
instance with a frozen list ofHistorySlice
instances. Otherwise, all other internal references will refer back to the sourceKeyword
instance. Note that if a clone’sKeyword.read()
method is called, only the frozen values associated with the cloned instance will be returned.
-
convert
(binary=None, ascii=None)¶ Request a translation for either a KTL binary representation to its KTL ascii representation, or the other way around. You cannot simultaneously specify both binary and ascii values. The return result is the translated value.
-
isAlive
()¶ Check that the heartbeats associated with this keyword are themselves alive; if they are, return True, otherwise return False. If no heartbeats are associated with this
Keyword
instance, a NoHeartbeatsError exception will be raised.
-
lower
()¶ Return the lower-case equivalent of the current ascii value of this
Keyword
instance. If there is no current ascii value, an AttributeError exception will be raised.
-
monitor
(start=True, prime=True, wait=True)¶ Subscribe to broadcasts for this KTL keyword. If start is set to False, the subscription will be shut down. If prime is set to False, there will be no priming read of the keyword value; the default behavior is to perform a priming read. If wait is set to False, the priming read (if requested) will not block while waiting for the priming read to complete.
In order to avoid a race condition, priming reads are always performed as a distinct operation from the subscription request. Traditional KTL C usage combines the two in a single
ktl_read()
operation.
-
poll
(period=1, start=True)¶ In circumstances when a KTL keyword cannot (or will not) reliably broadcast updates, polling can be established. If start is True, a non-blocking call to
Keyword.read()
will be invoked every period seconds; if start is False, polling for this keyword will be discontinued.Polling keywords is inefficient, as it requires a discrete ktl_read() operation for each polling event for each keyword polled. Using
monitor()
is a far better choice if supported by the service’s KTL client library.
-
probe
()¶ Use the
Procedural.probe()
method to open/read/close this KTL service and keyword to see if out-of-band communication succeeds. There is no return result, exceptions are raised upon failure. It is highly recommended to try callingKeyword.read()
(possibly with a timeout) before calling this method; some services will restore themselves automatically without requiring aService.reconnect()
operation.
-
propagate
()¶ Invoke any/all callbacks registered via
Keyword.callback()
. This is an internal function, invoked after aKeyword
instance successfully completes aKeyword.read()
call, or a KTL broadcast event occurs.
-
read
(binary=False, both=False, wait=True, timeout=None)¶ Perform a
ktl_read()
operation for this keyword. The default behavior is to do a blocking read and return the ascii representation of the keyword value. If binary is set to True, only the binary representation will be returned; If both is set to True, both representations will be returned in a (binary, ascii) tuple. If wait is set to False, the KTL read operation will be performed in a background thread, and any resulting updates would trigger any callbacks registered viaKeyword.callback()
. If a timeout is specified (in seconds), and wait is set to True,Keyword.read()
will raise aTimeoutException
if the timeout expires before a response is received.In order to avoid the possibility of a silent deadlock, the timeout argument is only respected if the service supports KTL_NOTIFY read operations.
-
subscribe
(start=True, prime=True, wait=True)¶ Subscribe to broadcasts for this KTL keyword. If start is set to False, the subscription will be shut down. If prime is set to False, there will be no priming read of the keyword value; the default behavior is to perform a priming read. If wait is set to False, the priming read (if requested) will not block while waiting for the priming read to complete.
In order to avoid a race condition, priming reads are always performed as a distinct operation from the subscription request. Traditional KTL C usage combines the two in a single
ktl_read()
operation.
-
upper
()¶ Return the upper-case equivalent of the current ascii value of this
Keyword
instance. If there is no current ascii value, an AttributeError exception will be raised.
-
wait
(timeout=None, operator=None, value=None, sequence=None, reset=False, case=False)¶ Wait for the Keyword to receive a new value, or if sequence is set, wait for the designated write operation to complete. If value is set, with or without operator being set,
Keyword.wait()
effectively acts as a wrapper toKeyword.waitFor()
. If reset is set to True, the notification flag will be cleared before waiting against it– this is dangerous, as this introduces a race condition between the arrival of the event itself, and the invocation ofKeyword.wait()
. If the event occurs first, the caller may wind up waiting indefinitely. If timeout (in whole or partial seconds) is set,Keyword.wait()
will return False if no update occurs before the timeout expires. Otherwise,Keyword.wait()
returns True to indicate that the wait completed successfully.
-
waitFor
(expression, timeout=None, case=False)¶ Wait until this Keyword satisfies the provided expression. If timeout seconds elapse without success,
Keyword.waitFor()
will return False. This Keyword is always prefixed to the expression as the implied first argument.See the documentation on Expressions in KTL Python for syntax details.
-
write
(value, wait=True, binary=False, timeout=None)¶ Perform a KTL write for this keyword. value is the new value to write to the keyword. If binary is set to True, value will be interpreted as a binary representation; the default behavior is to interpret value as an ascii representation. The behavior of timeout is the same as for
Keyword.read()
.Keyword.write()
does not update theKeyword
instance with new values. AKeyword
instance will only update its internal values as a result of aKeyword.read()
call, or if the Keyword is subscribed to broadcasts viaKeyword.monitor()
.
-
Other objects¶
-
class
ktl.
HistorySlice
(keyword, binary, ascii, time)¶ A HistorySlice is effectively a named tuple, an object type available in Python 2.6 and later. A HistorySlice provides programmer-friendly access to the data resulting from a single KTL broadcast.
Available keys are as follows:
Key Value 0 or time or timestamp UNIX timestamp for the broadcast 1 or bin or binary Binary representation of keyword 2 or asc or ascii Ascii representation of keyword keyword or name Name of KTL keyword