Update channel filter documentation, adding $ syntax

This commit is contained in:
Andrew Johnson
2022-12-28 15:52:30 -06:00
parent 5759726a89
commit 05cd7edf71

View File

@@ -1,59 +1,214 @@
=head1 Channel Filters
=title Field Modifiers and Channel Filters
Channel Filters can be applied to Channel Access channels by a client, using
a JSON Field Modifier to select the filter and any parameters.
The following filters are available in this release:
=head2 Contents
=over
=item * L<TimeStamp|/"TimeStamp Filter ts">
=item * L<Introduction
|/"Introduction">
=item * L<Deadband|/"Deadband Filter dbnd">
=item * L<Using Field Modifiers and Channel Filters
|/"Using Field Modifiers and Channel Filters">
=item * L<Array|/"Array Filter arr">
=item * L<Example Filters
|/"Example Filters">
=item * L<Synchronize|/"Synchronize Filter sync">
=item * L<Field Modifier Reference
|/"Field Modifier Reference">
=item * L<Decimation|/"Decimation Filter dec">
=over
=item * L<UTag|/"UTag Filter utag">
=item * L<Long String Modifier C<$>
|/"Long String Field Modifier $">
=item * L<Subarray Modifier C<<< [E<hellip>] >>>
|/"Subarray Field Modifier [start:increment:end]">
=back
=head2 Using Filters
=item * L<JSON5 Channel Filters
|/"JSON5 Channel Filters">
Channel filters can be added to any Channel Access channel name.
There can be more than one filter applied to the same channel, in which case the
order that they are specified will control the order in which they are applied
to the resulting data-stream.
The filter specification must appear after the field name, or if the default
(VAL) field is used after a dot C<.> appended to the record name.
With the exception of the array short-hand which is described below, all filters
must appear inside a pair of braces C< {} > after the dot expressed as a JSON
(L<JavaScript Object Notation|http://www.json.org/>) object, which allows filter
parameters to be included as needed.
=over
Each filter is given as a name/value pair. The filter name (given in parentheses
in the titles below) is a string, and must be enclosed inside double-quotes C<">
characters as per the JSON specification.
Parameters to that filter are provided as the value part of the name/value pair,
and will normally appear as a child JSON object consisting of name/value pairs
inside a nested pair of braces C< {} >.
=item * L<TimeStamp Filter C<<< {ts:{}} >>>
|/"TimeStamp Filter ts">
=head4 Example Filter
=item * L<Deadband Filter C<<< {dbnd:{E<hellip>}} >>>
|/"Deadband Filter dbnd">
Given a record called C<test:channel> the following would apply a filter C<f> to
the VAL field of that record, giving the filter two numeric parameters named
C<lo> and C<hi>:
=item * L<Array Filter C<<< {arr:{E<hellip>}} >>>
|/"Array Filter arr">
test:channel.{"f":{"lo":0,"hi":10}}
=item * L<Synchronize Filter C<<< {sync:{E<hellip>}} >>>
|/"Synchronize Filter sync">
Note that due to the required presence of the double-quote characters in the
JSON strings in the name string, it will usually be necessary to enclose a
filtered name within single-quotes C<< ' ... ' >> when typing it as an
argument to a Unix shell command.
=item * L<Decimation Filter C<<< {dec:{E<hellip>}} >>>
|/"Decimation Filter dec">
=head2 Filter Reference
=item * L<User Tag Filter C<<< {utag:{E<hellip>}} >>>
|/"User Tag Filter utag">
=back
=back
=head2 Introduction
A Field Modifier is a string that is appended to the field name part of a
Channel Access or PV Access channel name of an IOC-based server.
The IOC currently recognizes 3 different kinds of field modifier, which are
described below.
A Channel Filter is an IOC plugin that can be attached to an IOC process
variable channel using a field modifier, and can alter the data updates that are
served to the client that requested the filtering.
Clients that use a channel filter have no effect on other clients connected to
the same PV.
Filters can only modify or drop monitor events that the IOC posts; introducing
extra monitor events (in between the events posted by the IOC itself) is not
currently possible.
Most Channel Filters are configured by a field modifier that uses JSON5
syntax to select the type of filter and provide any parameters it accepts.
=head2 Using Field Modifiers and Channel Filters
Modifiers can be added to any Channel Access or PV Access channel name.
There can be more than one modifier or filter applied to a channel.
Modifiers must appear immediately after the field name if one is included in the
channel name.
If no field is named because the default (VAL) field is the target, the
modifiers must come immediately after a dot C<.> appended to the record name.
The order that modifiers and filters are specified controls the order in which
they are applied to the resulting data-stream.
If used, the Long String and Subarray field modifiers must appear first and in
that order, followed by any channel filters inside a pair of braces C< {} > that
form a JSON5 (L<JavaScript Object Notation|https://spec.json5.org/>) map, which
allows filters and their parameters to be specified as needed.
Each JSON5 filter is specified as a name:value pair.
The filter name is a map key that may be an unquoted identifier name (which all
of the filter names given below are), or a string enclosed inside either single-
or double-quote characters C<'> or C<"> as per the JSON5 specification.
Parameters to the filter are provided in the value part of the key:value pair
after the colon C<:> character, and will normally be an embedded JSON5 map
containing zero or more key/value pairs inside a nested pair of braces C< {} >.
Unless included inside a quoted string, white space characters are ignored and
skipped over by the JSON5 parser between other token characters.
This includes horizontal and vertical tabs, line feed/form feed/carriage return,
space and the non-breaking space character C< \xA0 >.
Within a quoted string, line breaks may escaped with a backslash C<\> to be
omitted from the parsed string.
An IOC Channel Access link can include filters in its channel name, but it is
important to not include any spaces at all in the filter specification.
If a filter name or parameter must contain a space it will be necessary to
express that space character as an escaped character C<\x20> or C<\u0020> inside
a quoted string, otherwise the space will mark the end of the channel name to
the link parsing code inside the IOC.
=head4 Example Filters
Given a record called C<test:channel> the following would all apply a channel
filter C<f> to the VAL field of that record, giving the filter two numeric
parameters named C<lo> and C<hi>:
test:channel.{f:{lo:0,hi:10}}
test:channel.{"f":{"lo":0, "hi":10}}
test:channel.{'f': {'lo':0, 'hi':10} }
When typing a filtered channel name as an argument to a Unix shell command, if
quote characters are used for keys or values in JSON strings within the channel
name string it may be necessary to enclose the name within quotes C<'> or C<">
or to use back-slash escapes before them.
Quotes may not be required when the Long String modifier C<$> is used at the end
of a field name with nothing following it, but will be necessary for a square
bracketted Subarray filter or if a dollar sign is followed by something else.
Hal$ caget test:channel.{f:{lo:0,hi:10}}
...
Hal$ caget 'test:channel.{"f":{"lo":0, "hi":10}}'
...
Hal$ caget -S calc:record.CALC$
...
Hal$ caget -S 'test:channel.NAME$[0:4]'
test:channel.NAME$[0:4] test
=head2 Field Modifier Reference
The two built-in field modifiers use a simplified syntax following the record
field name.
=head3 Long String Field Modifier C<$>
Appending a dollar sign C<$> to the name of a C<DBF_STRING> field causes the IOC
to change the representation of that field into an array of characters, which
allows strings longer than 40 character to be transported through Channel
Access.
Long strings are particularly useful for the CALC fields of a calculation or
calcout record, which can hold up to 80 characters, or the VAL fields of an lsi
(Long String Input) or lso (Long String Output) record which can be any length
as chosen by the database designer.
Hal$ cainfo test:channel.NAME
test:channel.NAME
State: connected
Host: 10.234.56.78:5064
Access: read, no write
Native data type: DBF_STRING
Request type: DBR_STRING
Element count: 1
Hal$ cainfo test:channel.NAME$
test:channel.NAME$
State: connected
Host: 10.234.56.78:5064
Access: read, no write
Native data type: DBF_CHAR
Request type: DBR_CHAR
Element count: 61
A CA client accessing a channel that uses the Long String field modifier will
have to be specifically configured to treat the data as a string instead of the
array of C<DBF_CHAR> that it looks like.
CA clients should not attempt to parse the channel name themselves to recognize
this field modifier in the name.
All long string values returned by the IOC should include a trailing zero byte
in their data as is standard for strings in the C language.
For the catools programs provided with Base, the flag C<-S> indicates that a
channel containing a character array should be treated as a long string.
Hal$ caget test:channel.NAME
test:channel.NAME test:channel
Hal$ caget test:channel.NAME$
test:channel.NAME$ 61 116 101 115 116 58 99 104 97 110 110 101 108 0 0 ...
Hal$ caget -S test:channel.NAME$
test:channel.NAME$ test:channel
=head3 Subarray Field Modifier C<[start:increment:end]>
This square-bracket field modifier syntax gets translated within the IOC into
calls to the L<Array Filter|/"Array Filter arr">, see that section below for
details of this shorthand.
The subarray field modifier syntax can immediately follow a Long String field
modifier, which permits fetching various kinds of substrings from the field.
This syntax cannot appear after a JSON filter specification though, the JSON
"arr" filter syntax must be used to apply an array filter after any other JSON
filter type.
Hal$ caget -S 'test:channel.NAME$[0:4]'
test:channel.NAME$[0:4] test
Hal$ caget -S 'test:channel.NAME$[5:-1]'
test:channel.NAME$[5:-1] channel
=head2 JSON5 Channel Filters
=cut
@@ -61,11 +216,11 @@ registrar(tsInitialize)
=head3 TimeStamp Filter C<"ts">
This filter is used to set the timestamp of the value fetched through
the channel to the time the value was fetched (or an update was sent),
rather than the time the record last
processed which could have been days or even weeks ago for some records, or set
to the EPICS epoch if the record has never processed.
This filter replaces the timestamp in the data fetched through the channel with
the time the value was fetched (or an update was sent). The record's timestamp
indicates when the record last processed, which could have been days or even
weeks ago for some records, or set to the EPICS epoch if the record has never
processed.
=head4 Parameters
@@ -125,7 +280,7 @@ The default mode is C<abs> if no mode parameter is included.
test:channel 2012-09-01 22:10:23.601023 5
test:channel 2012-09-01 22:10:24.601136 6 HIGH MINOR
^C
Hal$ camonitor 'test:channel.{"dbnd":{"abs":1.5}}'
Hal$ camonitor 'test:channel.{"dbnd":{"d":1.5}}'
test:channel.{"dbnd":{"d":1.5}} 2012-09-01 22:11:49.613341 1 LOLO MAJOR
test:channel.{"dbnd":{"d":1.5}} 2012-09-01 22:11:51.613615 3 LOW MINOR
test:channel.{"dbnd":{"d":1.5}} 2012-09-01 22:11:53.613804 5
@@ -144,16 +299,21 @@ subarrays).
=head4 Parameters
Note: Negative index numbers address from the end of the array, with C<-1> being the last element.
=over
=item Square bracket notation C<[start:increment:end]> (shorthand)
The common square bracket notation which can be used in place of JSON.
This much shorter square bracket notation can be used in place of JSON.
Any parameter may be omitted (keeping the colons) to use the default value.
If only one colon is included, this means C<[start:end]> with an increment of 1.
If only a single parameter is used C<[index]> the filter returns one element.
If only one colon is included, it means C<[start:end]> with an increment of 1.
If only a single parameter is given C<[index]> the filter returns one element.
Index numbers for the start and end parameters must be integers, with the first
array element being found at index C<0>.
The value of an index may be negative, in which case the indexing is counted
backwards from the end of the array, with C<-1> being the last element.
If the start index selects an element that comes after the end index element,
the subarray returned will always be empty.
=item Start index C<"s">
@@ -161,8 +321,8 @@ Index of the first original array element to retrieve.
=item Increment C<"i">
Index increment between retrieved elements of the original array; must be
a positive number.
The stride or increment to apply between elements of the original array to be
retrieved. This value must be a positive integer.
=item End index C<"e">
@@ -176,9 +336,9 @@ C<s=0> (first element), C<i=1> (fetch all elements), C<e=-1>
=head4 Example
Hal$ caget test:channel 'test:channel.{"arr":{"s":2,"i":2,"e":8}}' test:channel.[3:5] test:channel.[3:2:-3]
Hal$ caget test:channel 'test:channel.{"arr":{s:2,i:2,e:8}}' test:channel.[3:5] test:channel.[3:2:-3]
test:channel 10 0 1 2 3 4 5 6 7 8 9
test:channel.{"arr":{"s":2,"i":2,"e":8}} 4 2 4 6 8
test:channel.{"arr":{s:2,i:2,e:8}} 4 2 4 6 8
test:channel.[3:5] 3 3 4 5
test:channel.[3:2:-3] 3 3 5 7
@@ -202,13 +362,14 @@ C<dbStateSet()>.
=item Mode+State
Mode and state can be specified in one definition (shorthand).
The desired mode is given as parameter name (C<"before"> / C<"first"> /
C<"while"> / C<"last"> / C<"after"> / C<"unless">), with the state name
(enclosed in double quotes C<">) as value.
The desired mode is given as the parameter name (C<"before"> / C<"first"> /
C<"while"> / C<"last"> / C<"after"> / C<"unless"> which may be unquoted), with
the state name (enclosed in single or double quotes C<"> or C<'>) as the value.
=item Mode C<"m">
A single word from the list below, enclosed in double quotes C<">.
A single word from the list below, enclosed in single or double quotes C<'> or
C<">.
This controls how the state value should affect the monitor stream.
=over
@@ -235,7 +396,7 @@ as the state is false.
=item State C<"s">
The name of a state variable, enclosed in double quotes C<">.
The name of a state variable, enclosed in single or double quotes C<"> or C<'>.
=back
@@ -245,7 +406,7 @@ Assuming there is a system state called "blue", that is being controlled by
some other facility such as a timing system, updates could be restricted to
periods only when "blue" is true by using
Hal$ camonitor 'test:channel' 'test:channel.{"sync":{"while":"blue"}}'
Hal$ camonitor 'test:channel' 'test:channel.{sync:{while:"blue"}}'
...
=cut
@@ -283,17 +444,18 @@ client connects.
To sample a 60Hz channel at 1Hz, a 10Hz channel every 6 seconds or a 1Hz channel
once every minute:
Hal$ camonitor 'test:channel' 'test:channel.{"dec":{"n":60}}'
Hal$ camonitor 'test:channel' 'test:channel.{dec:{n:60}}'
...
=cut
registrar(utagInitialize)
=head3 UTag Filter C<"utag">
=head3 User Tag Filter C<"utag">
This filter applies a test UTAG&M==V to the value taken from the UTAG record field
and drops those updates which evaluate as false.
This filter applies a test C< (UTAG & M) == V > to the value of the record's
UTAG field at the time each monitor event is posted, and drops all updates for
which this expression is false.
=head4 Parameters
@@ -301,12 +463,19 @@ and drops those updates which evaluate as false.
=item Mask C<"M">
Bit mask.
An integer to be used as a bit mask.
=item Value C<"V">
Required value.
The integer value to be matched after applying the mask to the UTAG value.
=back
=head4 Example
To read a channel only when the UTAG value is even (bit 0 is 0):
Hal$ camonitor 'test:channel' 'test:channel.{utag:{m:1, v:0}}'
...
=cut