camonitor_parse
index
/home/goetz/project-shared/publish-HZB/projects/bii_scripts/bii_scripts/lib/python/bii_scripts/camonitor_parse.py

camonitor_parse
 
parse the output of camonitor.

 
Modules
       
datetime
re

 
Functions
       
convert_line_datatypes(tp, parse_numbers, parse_date, extra_indices=None)
do data converstions on output of parse_line.
 
arguments:
- tp: The tuple returned by parse_line()
- parse_numbers: Convert value(s) to numbers, if possible
- parse_date: Convert the timestamp to a datetime.datetime object, if
      possible.
- extra_indices: an extra list of indices in tp that is printed, too
 
returns:
  A tuple (pv, time, value, flags, status). The fields are the same as
  decribed at parse_line() except that value(s) may be converted to numbers
  and time may be a datetime.datetime object.
create_line(d, rm_timestamp, delimiter, extra_indices=None)
re-create line from dict.
 
arguments:
  - d: Tuple created by parse_line()
  - rm_timestamp: if True, the timestamp is not printed
  - delimiter: delimiter of fields, if None, do separate the fields exactly
    the way 'camonitor' does.
  - extra_indices: an extra list of indices in d that is printed, too
date2str(d)
create date string as it is used by camonitor.
parse_date_str(st)
parse a date string.
 
Here are some examples:
 
>>> parse_date_str("2023-01-29T12:13:14.567891")
datetime.datetime(2023, 1, 29, 12, 13, 14, 567891)
>>> parse_date_str("2023-01-29 12:13:14.567891")
datetime.datetime(2023, 1, 29, 12, 13, 14, 567891)
>>> parse_date_str("2023-01-29T12:13:14")
datetime.datetime(2023, 1, 29, 12, 13, 14)
>>> parse_date_str("2023-01-29 12:13:14")
datetime.datetime(2023, 1, 29, 12, 13, 14)
>>> parse_date_str("2023-01-29T12:13")
datetime.datetime(2023, 1, 29, 12, 13)
>>> parse_date_str("2023-01-29 12:13")
datetime.datetime(2023, 1, 29, 12, 13)
>>> parse_date_str("2023-01-29T12")
datetime.datetime(2023, 1, 29, 12, 0)
>>> parse_date_str("2023-01-29 12")
datetime.datetime(2023, 1, 29, 12, 0)
>>> parse_date_str("2023-01-29")
datetime.datetime(2023, 1, 29, 0, 0)
>>> parse_date_str("2023-01")
datetime.datetime(2023, 1, 1, 0, 0)
>>> parse_date_str("2023")
datetime.datetime(2023, 1, 1, 0, 0)
parse_line(line, keep_undefined)
parse a single line.
 
arguments:
  - line: The line created by 'camonitor'
  - keep_undefined: If True, keep lines where the time stamp is not defined
    or where only a status but no value is found.
 
returns:
  A tuple (pv, time, value, flags, status), tuple fields:
 
  - pv: The process variable name, a string
  - time:
      - None : time was not specified
      - ""   : time was undefined ('<undefined>')
      - str  : time string, YYYY-MM-DD HH:mm:SS.ffffff
  - value:
      - None : value was not given
      - ""   : value was empty string
      - str  : value
      - [str, str...]: value from a waveform record
  - flags: [flag, flag...]: A list of EPICS flags like "UDF" or "HIHI"
  - status:
      - None : no special statis given
      - str  : a status like "Not connected (PV not found)". Usually the
               status is not set. If it is set, there is no value and no
               time.
 
>>> def test(st, flg):
...     print(repr(parse_line(st, flg)))
...
>>> test("UE112ID7R:AdiAllPmsPosCnt      2023-02-23 00:29:47.934853 2011943  ", True)
('UE112ID7R:AdiAllPmsPosCnt', '2023-02-23 00:29:47.934853', '2011943', None, None)
>>> test("UE112ID7R:TestCnt              2023-02-23 00:29:47.944853 2.01301e+06  ", True)
('UE112ID7R:TestCnt', '2023-02-23 00:29:47.944853', '2.01301e+06', None, None)
>>> test("UE112ID7R:ETabRbkEnergy        2023-02-23 00:29:47.934853 nan UDF INVALID", True)
('UE112ID7R:ETabRbkEnergy', '2023-02-23 00:29:47.934853', 'nan', ['UDF', 'INVALID'], None)
>>> test("UE112ID7R:DiagSpdSet 2023-02-20 16:44:58.859846 2 1 1  ", True)
('UE112ID7R:DiagSpdSet', '2023-02-20 16:44:58.859846', ['1', '1'], None, None)
>>> test("UE112ID7R:verno                <undefined> 17.002 UDF INVALID", True)
('UE112ID7R:verno', '', '17.002', ['UDF', 'INVALID'], None)
>>> test("UE112ID7R:ETabEnM              <undefined>  UDF INVALID", True)
('UE112ID7R:ETabEnM', '', '', ['UDF', 'INVALID'], None)
>>> test("UE112ID7R:SDevHmeSttHme        <undefined> FALSE UDF INVALID", True)
('UE112ID7R:SDevHmeSttHme', '', 'FALSE', ['UDF', 'INVALID'], None)
>>> test("UE112ID7R:SDevHmeSttHme        <undefined> FALSE UDF INVALID", False)
('UE112ID7R:SDevHmeSttHme', '', 'FALSE', ['UDF', 'INVALID'], None)
>>> test("U17IT6R:AmsAi0Raw2             *** Not connected (PV not found)", True)
('U17IT6R:AmsAi0Raw2', None, None, None, '*** Not connected (PV not found)')
>>> test("U17IT6R:AmsAi0Raw2             *** Not connected (PV not found)", False)
None
st_is_num(st)
return if st is a number.
str2num(st)
convert to int/float if possible.

 
Data
        EPICS_FLAGS = {'BAD_SUB', 'CALC', 'COMM', 'COS', 'DISABLE', 'HIGH', ...}
I_FLAGS = 3
I_LAST = 4
I_PV = 0
I_STATUS = 4
I_TIME = 1
I_VALUE = 2
PV_COLUMN_WIDTH = 30
rx_float = re.compile('-?[Nn][Aa][Nn]|[+-]?[0-9]*\\.?[0-9]+([eE][+-]?[0-9]+)?$')
rx_int = re.compile('[+-]?[0-9]+$')
rx_pv = re.compile('(\\S+)\\s+(.*)')
rx_spc = re.compile('\\s')
rx_tm = re.compile('(<undefined>|\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}\\.\\d+)\\s(.*)')