Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

extended FSWTabDict class #377

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 9 additions & 10 deletions ait/core/cfg.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,15 @@
PATH_KEYS = 'directory', 'file', 'filename', 'path', 'pathname'

def expandConfigPaths (config, prefix=None, datetime=None, pathvars=None, parameter_key='', *keys):
"""Updates all relative configuration paths in dictionary config,
"""
Updates all relative configuration paths in dictionary config,
which contain a key in keys, by prepending prefix.

If keys is omitted, it defaults to 'directory', 'file',
'filename', 'path', 'pathname'.

See util.expandPath().

"""
if len(keys) == 0:
keys = PATH_KEYS
Expand Down Expand Up @@ -117,7 +119,6 @@ def replaceVariables(path, datetime=None, pathvars=None):
# get the list of possible variable values
value_list = v if type(v) is list else [ v ]


# create temp_list for now
temp_list = []

Expand Down Expand Up @@ -189,14 +190,12 @@ def merge (d, o):
return d



class AitConfigError(Exception):
"""Raised when a AIT configuration parameter is present, but
is in some way incorrect."""
pass



class AitConfigMissing(Exception):
"""Raised when a AIT configuration parameter is missing."""

Expand All @@ -207,9 +206,9 @@ def __init__(self, param):
self.param = param



class AitConfig (object):
"""AitConfig
"""
AitConfig

A AitConfig object holds configuration parameters read from a
YAML configuration file. The YAML data structure has three levels
Expand All @@ -218,6 +217,7 @@ class AitConfig (object):

NOTE: The platform string is Python's sys.platform, i.e. 'linux2',
'darwin', 'win32'.

"""
_ROOT_DIR = os.path.abspath(os.environ.get('AIT_ROOT', os.getcwd()))

Expand Down Expand Up @@ -333,12 +333,13 @@ def _datapaths(self):
return paths

def reload (self, filename=None, data=None):
"""Reloads the a AIT configuration.

"""
Reloads the a AIT configuration.
The AIT configuration is automatically loaded when the AIT
package is first imported. To replace the configuration, call
reload() (defaults to the current config.filename) or
reload(new_filename).

"""
if data is None and filename is None:
filename = self._filename
Expand All @@ -364,7 +365,6 @@ def reload (self, filename=None, data=None):
else:
self._config = { }


def get (self, name, default=None):
"""Returns the attribute value *AitConfig.name* or *default*
if name does not exist.
Expand Down Expand Up @@ -393,7 +393,6 @@ def get (self, name, default=None):

return config[tail] if tail in config else default


def getDefaultFilename(self):
if 'AIT_CONFIG' in os.environ:
filename = os.path.abspath(os.environ.get('AIT_CONFIG'))
Expand Down
62 changes: 41 additions & 21 deletions ait/core/cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

The ait.core.cmd module provides commands and command dictionaries.
Dictionaries contain command and argument definitions.

"""

import os
Expand All @@ -43,6 +44,7 @@ class ArgDefn(json.SlotSerializer, object):

A fixed argument (fixed=True) defines a fixed bit pattern in that
argument's byte position(s).

"""
__slots__ = [
"name", "desc", "units", "_type", "bytes", "_enum", "range",
Expand Down Expand Up @@ -96,8 +98,10 @@ def startbit(self):
return self.slice().start % 2 * 8

def decode(self, bytes):
"""Decodes the given bytes according to this AIT Argument
"""
Decodes the given bytes according to this AIT Argument
Definition.

"""
value = self.type.decode(bytes)
if self._enum is not None:
Expand All @@ -108,18 +112,22 @@ def decode(self, bytes):
return value

def encode(self, value):
"""Encodes the given value according to this AIT Argument
"""
Encodes the given value according to this AIT Argument
Definition.

"""
if type(value) == str and self.enum and value in self.enum:
value = self.enum[value]
return self.type.encode(value) if self.type else bytearray()

def slice(self, offset=0):
"""Returns a Python slice object (e.g. for array indexing) indicating
"""
Returns a Python slice object (e.g. for array indexing) indicating
the start and stop byte position of this Command argument. The
start and stop positions may be translated by the optional byte
offset.

"""
if type(self.bytes) is int:
start = self.bytes
Expand All @@ -131,9 +139,11 @@ def slice(self, offset=0):
return slice(start + offset, stop + offset)

def validate(self, value, messages=None):
"""Returns True if the given Argument value is valid, False otherwise.
"""
Returns True if the given Argument value is valid, False otherwise.
Validation error messages are appended to an optional messages
array.

"""
valid = True
primitive = value
Expand Down Expand Up @@ -163,16 +173,19 @@ def log(msg):
return valid



class Cmd(object):
"""Cmd - Command
"""
Cmd - Command

Commands reference their Command Definition and may contain arguments.

"""
def __init__(self, defn, *args, **kwargs):
"""Creates a new AIT Command based on the given command
"""
Creates a new AIT Command based on the given command
definition and command arguments. A Command may be created
with either positional or keyword arguments, but not both.

"""
self.defn = defn

Expand All @@ -193,7 +206,6 @@ def __init__(self, defn, *args, **kwargs):
self.args = args
self._unrecognized = kwargs


def __repr__(self):
return self.defn.name + " " + " ".join([str(a) for a in self.args])

Expand Down Expand Up @@ -223,7 +235,8 @@ def argdefns(self):
return self.defn.argdefns

def encode(self, pad=106):
"""Encodes this AIT command to binary.
"""
Encodes this AIT command to binary.

If pad is specified, it indicates the maximum size of the encoded
command in bytes. If the encoded command is less than pad, the
Expand All @@ -233,6 +246,7 @@ def encode(self, pad=106):
(128 bytes) with 11 words (22 bytes) of CCSDS overhead (SSP
52050J, Section 3.2.3.4). This leaves 53 words (106 bytes) for
the command itself.

"""
opcode = struct.pack('>H', self.defn.opcode)
offset = len(opcode)
Expand All @@ -255,21 +269,24 @@ def encode(self, pad=106):
return encoded

def validate(self, messages=None):
"""Returns True if the given Command is valid, False otherwise.
"""
Returns True if the given Command is valid, False otherwise.
Validation error messages are appended to an optional messages
array.

"""
return self.defn.validate(self, messages)



class CmdDefn(json.SlotSerializer, object):
"""CmdDefn - Command Definition
"""
mdDefn - Command Definition

Command Definitions encapsulate all information required to define a
single command. This includes the command name, its opcode,
subsystem, description and a list of argument definitions. Name and
opcode are required. All others are optional.

"""
__slots__ = ( 'name', '_opcode', 'subsystem', 'ccsds', 'title', 'desc',
'argdefns' )
Expand All @@ -287,32 +304,37 @@ def __init__(self, *args, **kwargs):
if self.argdefns is None:
self.argdefns = []


def __repr__(self):
return util.toRepr(self)

@property
def args (self):
"""The argument definitions to this command (excludes fixed
"""
The argument definitions to this command (excludes fixed
arguments).

"""
return filter(lambda a: not a.fixed, self.argdefns)

@property
def nargs(self):
"""The number of arguments to this command (excludes fixed
"""
The number of arguments to this command (excludes fixed
arguments).

"""
return len(list(self.args))

@property
def nbytes(self):
"""The number of bytes required to encode this command.
"""
The number of bytes required to encode this command.

Encoded commands are comprised of a two byte opcode, followed by a
one byte size, and then the command argument bytes. The size
indicates the number of bytes required to represent command
arguments.

"""
return len(self.opcode) + 1 + sum(arg.nbytes for arg in self.argdefns)

Expand Down Expand Up @@ -376,7 +398,6 @@ def validate(self, cmd, messages=None):
return valid



class CmdDict(dict):
"""CmdDict

Expand Down Expand Up @@ -412,7 +433,6 @@ def add(self, defn):
log.error(msg)
raise util.YAMLError(msg)


def create(self, name, *args, **kwargs):
"""Creates a new AIT command with the given arguments."""
tokens = name.split()
Expand All @@ -434,7 +454,6 @@ def create(self, name, *args, **kwargs):

return createCmd(defn, *args, **kwargs)


def decode(self, bytes):
"""Decodes the given bytes according to this AIT Command
Definition.
Expand Down Expand Up @@ -486,7 +505,6 @@ def toJSON(self):
return { name: defn.toJSON() for name, defn in self.items() }



def getDefaultCmdDict(reload=False):
return getDefaultDict(reload=reload)

Expand Down Expand Up @@ -539,14 +557,16 @@ def YAMLCtor_CmdDefn(loader, node):
fields['argdefns'] = fields.pop('arguments', None)
return createCmdDefn(**fields)


def YAMLCtor_include(loader, node):
# Get the path out of the yaml file
name = os.path.join(os.path.dirname(loader.name), node.value)
data = None
with open(name,'r') as f:
data = yaml.load(f)
data = yaml.load(f, Loader=yaml.Loader)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this necessary?

Copy link
Author

@JimHofman JimHofman Mar 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took out loader=yaml.loader.
We might want to get rid of data=None and use a try/except around the open block.

return data


yaml.add_constructor('!include' , YAMLCtor_include)
yaml.add_constructor('!Command' , YAMLCtor_CmdDefn)
yaml.add_constructor('!Argument', YAMLCtor_ArgDefn)
Expand Down
2 changes: 1 addition & 1 deletion ait/core/dtype.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
import sys
import re

from ait.core import cmd, dmc, log, util
from ait.core import cmd, dmc, log, util, table
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

table is not reference in this module



# PrimitiveTypes
Expand Down
Loading