Source code for irfpy.mexop.imastatus

''' Calculate the IMA status from event file

The module provides states of MEX/IMA at a specified time.
The states include on/off, eeprom section, mode, deflection, or PACC.
These information are retrieved from so-called ASPERA event file.
http://aspera-3.irf.se/archive/commanding/pors/EV_ASPERA.MEX
This module is still alpha version, so that a big changes in 
API may change in the future version.

Usage:

>>> import datetime
>>> state = get_status(datetime.datetime(2006, 12, 5, 15, 0, 0))
>>> print(state)
<ON:True/PAC:4.0/EEPR:0/MOD:24.0/DEF:True>
>>> print(state.on)
True
>>> print(state.pacc)
4.0
>>> print(state.eeprom)
0
>>> print(state.mode)
24.0
>>> print(state.deflector)
True

>>> print(get_status(datetime.datetime(2004, 1, 24, 10, 0, 0)))
<ON:False/PAC:False/EEPR:False/MOD:False/DEF:False>

>>> print(get_status(datetime.datetime(2003, 1, 1, 0, 0, 0)))
<ON:None/PAC:None/EEPR:None/MOD:None/DEF:None>

'''

import copy
import logging
import bisect
import warnings

from collections import OrderedDict
from irfpy.mexop import eventfile

[docs]def parse_eventfile(): logger = logging.getLogger('parse_eventfile') # logger.setLevel(logging.INFO) ef = eventfile.default_eventfile() logger.debug(ef) status = Status() history = OrderedDict() for l in ef.list: cmd = l.cmdname # logger.debug('%s %s' % (str(l), str(cmd))) if cmd == 'AASF09A1': status.on = True status.eeprom = 0 status.hv = status.pacc = status.mode = status.deflector = None status.deflector = True # As a default, deflector may be set to True. elif cmd == 'AASF09B1': status.on = True status.eeprom = 1 status.hv = status.pacc = status.mode = status.deflector = None status.deflector = True # As a default, deflector may be set to True. elif cmd == 'AASF09C1': status.on = True status.eeprom = float(l.parameters['VAS04051']) + 1 status.hv = status.pacc = status.mode = status.deflector = None status.deflector = True # As a default, deflector may be set to True. elif cmd == 'AASF10A1' or cmd == 'AASF40D0': # IMA OFF, AS OFF status = Status() status.on = status.hv = status.pacc = status.mode = status.eeprom = status.deflector = False elif cmd == 'AASF23E1': # IMA ENTRANCE REFERENCE status.deflector = float(l.parameters['VAS05058']) status.hv = True elif cmd == 'AASF23I1': # IMA PACC status.pacc = float(l.parameters['VAS05055']) status.hv = True elif cmd == 'AASF60A1': # IMA mode status.mode = float(l.parameters['VAS05010']) elif cmd == 'AASF40A0': # IMA HV activate status.on = True status.pacc = 4 status.eeprom = 16 status.mode = 24 elif cmd == 'AASF40B0': # IMA HV activate status.hv = True # status.pacc = 4 # TBC!!, Likely not with this command. status.deflector = True # As a default, deflector may be set to True. elif cmd == 'AASF40C0': # IMA HV disable status.hv = False elif cmd == 'AASF40K0': # IMA HV activate with PACC status.hv = True # status.pacc = 4 # TBC!!, Likely not with this command. status.deflector = True # As a default, deflector may be set to True. history[l.utc] = l, copy.copy(status) logger.debug('%s %s' % (str(l), str(status))) warnings.warn('Check the AASF40 command to MH/LK.') return history
__parsed_event = None ''' Parsed event file. ''' def __parse(): global __parsed_event if __parsed_event is None: __parsed_event = parse_eventfile()
[docs]class Status: ''' A status ''' def __init__(self): self.on = None ''' ON/OFF/Unknown. True for ON, False for OFF, None for Unknown. ''' self.hv = None ''' ON/OFF/Unknown. True for ON, False for OFF, None for Unknown. ''' self.pacc = None ''' PACC used None for unknown (or default). 0-7. ''' self.eeprom = None ''' EEPROM section to be booted. None for unknown. 0 is booted from PROM. This is used in the first period of the mission. 1-16 is booted from EEPROM. The exact page number is to be decremented (0-15). For example, if the operation command states the boot of EEPROM=0, this attribute is set to 1. This is the same behaviour in the IMA telemetry's standard header (see VE-ASP-MA-0009, section 7.5, 8th byte 4-0 bit.) ''' self.mode = None ''' Mode. ''' self.deflector = None ''' Deflector, True=On, Number=reference or None=unknown. ''' def __str__(self): return '<ON:{0}/PAC:{2}/EEPR:{3}/MOD:{4}/DEF:{5}>'.format( self.on, self.hv, self.pacc, self.eeprom, self.mode, self.deflector, ) def __repr__(self): return self.__str__()
[docs]def get_status(t): ''' Return the :class:`Status` for given time ''' __parse() utcs = list(__parsed_event.keys()) idx = bisect.bisect(utcs, t) - 1 if idx < 0: return Status() # before the datafile logger = logging.getLogger('get_status') # logger.setLevel(logging.INFO) logger.debug('EVNT=%s CMD=%s' % (str(__parsed_event[utcs[idx]][0]), str(__parsed_event[utcs[idx]][1]))) return __parsed_event[utcs[idx]][1] # Return the Status.
[docs]def isdb(): ''' Return if the event file is available or not ''' try: __parse() except IOError: return False return __parsed_event is not None
import unittest import doctest
[docs]def doctests(): return unittest.TestSuite(( doctest.DocTestSuite(), ))
if __name__ == '__main__': unittest.main(defaultTest='doctests')