Exemplo n.º 1
0
def model_filename_to_id(filename):
    f = filename
    if '.' in f:
        f = os.path.splitext(f)[0]
    try:
        mid = int(f.rsplit('_', 1)[1])
    except ValueError:
        raise mdef.ModelDefinitionError(
            'Error extracting model id from filename')

    return mid
Exemplo n.º 2
0
def get_model_def(model_id, mapping=True):
    try:
        model_id = int(model_id)
    except:
        raise mdef.ModelDefinitionError('Invalid model id: %s' % model_id)

    model_def_file_json = mdef.to_json_filename(model_id)
    model_def_file_smdx = smdx.to_smdx_filename(model_id)
    model_def = None
    for path in model_defs_path:
        # look in directory, then json/, then smdx/
        for path_option in model_path_options:
            try:
                model_def = mdef.from_json_file(
                    os.path.join(path, path_option, model_def_file_json))
            except FileNotFoundError:
                pass
            except Exception as e:
                raise mdef.ModelDefinitionError(
                    'Error loading model definition for model %s: %s' %
                    (model_id, str(e)))

            if model_def is None:
                try:
                    model_def = smdx.from_smdx_file(
                        os.path.join(path, path_option, model_def_file_smdx))
                except FileNotFoundError:
                    pass
                except Exception as e:
                    raise mdef.ModelDefinitionError(
                        'Error loading model definition for model %s: %s' %
                        (model_id, str(e)))

            if model_def is not None:
                if mapping:
                    add_mappings(model_def[mdef.GROUP])
                return model_def
    raise mdef.ModelDefinitionError(
        'Model definition not found for model %s\nLooking in: %s' %
        (model_id, os.path.join(path, path_option, model_def_file_json)))
Exemplo n.º 3
0
def set_model_defs_path(path_list):
    if not isinstance(path_list, list):
        raise mdef.ModelDefinitionError(
            'Invalid path list type, path list is not a list')
    global model_defs_path
    model_defs_path = path_list
Exemplo n.º 4
0
def from_smdx_point(element):
    """ Sets the point attributes based on an element tree point element
    contained in an SMDX model definition.

    Parameters:

        element :
            Element Tree point type element.

        strings :
            Indicates if *element* is a subelement of the 'strings'
            definintion within the model definition.
    """
    point_def = {}
    pid = element.attrib.get(SMDX_ATTR_ID)
    if pid is None:
        raise mdef.ModelDefinitionError('Missing point id attribute')
    point_def[mdef.NAME] = pid
    ptype = element.attrib.get(SMDX_ATTR_TYPE)
    if ptype is None:
        raise mdef.ModelDefinitionError(
            'Missing type attribute for point: %s' % pid)
    elif ptype not in smdx_type_types:
        raise mdef.ModelDefinitionError('Unknown point type %s for point %s' %
                                        (ptype, pid))
    point_def[mdef.TYPE] = ptype
    plen = mdef.to_number_type(element.attrib.get(SMDX_ATTR_LEN))
    if ptype == SMDX_TYPE_STRING:
        if plen is None:
            raise mdef.ModelDefinitionError(
                'Missing len attribute for point: %s' % pid)
        point_def[mdef.SIZE] = plen
    mandatory = element.attrib.get(SMDX_ATTR_MANDATORY, SMDX_MANDATORY_FALSE)
    if mandatory not in smdx_mandatory_types:
        raise mdef.ModelDefinitionError('Unknown mandatory type: %s' %
                                        mandatory)
    if mandatory == SMDX_MANDATORY_TRUE:
        point_def[mdef.MANDATORY] = smdx_mandatory_types.get(mandatory)
    access = element.attrib.get(SMDX_ATTR_ACCESS, SMDX_ACCESS_R)
    if access not in smdx_access_types:
        raise mdef.ModelDefinitionError('Unknown access type: %s' % access)
    if access == SMDX_ACCESS_RW:
        point_def[mdef.ACCESS] = smdx_access_types.get(access)
    units = element.attrib.get(SMDX_ATTR_UNITS)
    if units:
        point_def[mdef.UNITS] = units
    # if scale factor is an number, convert to correct type
    sf = mdef.to_number_type(element.attrib.get(SMDX_ATTR_SF))
    if sf is not None:
        point_def[mdef.SF] = sf
    # if scale factor is an number, convert to correct type
    value = mdef.to_number_type(element.attrib.get(SMDX_ATTR_VALUE))
    if value is not None:
        point_def[mdef.VALUE] = value

    symbols = []
    for e in element.findall('*'):
        if e.tag == SMDX_SYMBOL:
            sid = e.attrib.get(SMDX_ATTR_ID)
            value = e.text
            try:
                value = int(value)
            except ValueError:
                pass
            symbols.append({mdef.NAME: sid, mdef.VALUE: value})
    if symbols:
        point_def[mdef.SYMBOLS] = symbols

    return point_def
Exemplo n.º 5
0
def from_smdx(element):
    """ Sets the model type attributes based on an element tree model type
    element contained in an SMDX model definition.

    Parameters:

        element :
            Element Tree model type element.
    """

    model_def = {}

    m = element.find(SMDX_MODEL)
    if m is None:
        raise mdef.ModelDefinitionError('Model definition not found')
    try:
        mid = mdef.to_number_type(m.attrib.get(SMDX_ATTR_ID))
    except ValueError:
        raise mdef.ModelDefinitionError('Invalid model id: %s' %
                                        m.attrib.get(SMDX_ATTR_ID))

    name = m.attrib.get(SMDX_ATTR_NAME)
    if name is None:
        name = 'model_' + str(mid)
    model_def[mdef.NAME] = name

    strings = element.find(SMDX_STRINGS)

    # create top level group with ID and L points
    fixed_def = {
        mdef.NAME:
        name,
        mdef.TYPE:
        mdef.TYPE_GROUP,
        mdef.POINTS: [{
            mdef.NAME: 'ID',
            mdef.VALUE: mid,
            mdef.DESCRIPTION: 'Model identifier',
            mdef.LABEL: 'Model ID',
            mdef.MANDATORY: mdef.MANDATORY_TRUE,
            mdef.STATIC: mdef.STATIC_TRUE,
            mdef.TYPE: mdef.TYPE_UINT16
        }, {
            mdef.NAME: 'L',
            mdef.DESCRIPTION: 'Model length',
            mdef.LABEL: 'Model Length',
            mdef.MANDATORY: mdef.MANDATORY_TRUE,
            mdef.STATIC: mdef.STATIC_TRUE,
            mdef.TYPE: mdef.TYPE_UINT16
        }]
    }

    repeating_def = None

    fixed = None
    repeating = None
    for b in m.findall(SMDX_BLOCK):
        btype = b.attrib.get(SMDX_ATTR_TYPE, SMDX_ATTR_TYPE_FIXED)
        if btype == SMDX_ATTR_TYPE_FIXED:
            if fixed is not None:
                raise mdef.ModelDefinitionError(
                    'Duplicate fixed block type definition')
            fixed = b
        elif btype == SMDX_ATTR_TYPE_REPEATING:
            if repeating is not None:
                raise mdef.ModelDefinitionError(
                    'Duplicate repeating block type definition')
            repeating = b
        else:
            raise mdef.ModelDefinitionError('Invalid block type: %s' % btype)

    fixed_points_map = {}
    if fixed is not None:
        points = []
        for e in fixed.findall(SMDX_POINT):
            point_def = from_smdx_point(e)
            if point_def[mdef.NAME] not in fixed_points_map:
                fixed_points_map[point_def[mdef.NAME]] = point_def
                points.append(point_def)
            else:
                raise mdef.ModelDefinitionError(
                    'Duplicate point definition: %s' % point_def[mdef.NAME])
        if points:
            fixed_def[mdef.POINTS].extend(points)

    repeating_points_map = {}
    if repeating is not None:
        name = repeating.attrib.get(SMDX_ATTR_NAME)
        if name is None:
            name = 'repeating'
        repeating_def = {
            mdef.NAME: name,
            mdef.TYPE: mdef.TYPE_GROUP,
            mdef.COUNT: 0
        }
        points = []
        for e in repeating.findall(SMDX_POINT):
            point_def = from_smdx_point(e)
            if point_def[mdef.NAME] not in repeating_points_map:
                repeating_points_map[point_def[mdef.NAME]] = point_def
                points.append(point_def)
            else:
                raise mdef.ModelDefinitionError(
                    'Duplicate point definition: %s' % point_def[mdef.NAME])
        if points:
            repeating_def[mdef.POINTS] = points
        fixed_def[mdef.GROUPS] = [repeating_def]

    e = element.find(SMDX_STRINGS)
    if e.attrib.get(SMDX_ATTR_ID) == str(mid):
        m = e.find(SMDX_MODEL)
        if m is not None:
            for a in m.findall('*'):
                if a.tag == SMDX_LABEL and a.text:
                    fixed_def[mdef.LABEL] = a.text
                elif a.tag == SMDX_DESCRIPTION and a.text:
                    fixed_def[mdef.DESCRIPTION] = a.text
                elif a.tag == SMDX_NOTES and a.text:
                    fixed_def[mdef.DETAIL] = a.text
        for p in e.findall(SMDX_POINT):
            pid = p.attrib.get(SMDX_ATTR_ID)
            label = desc = notes = None
            for a in p.findall('*'):
                if a.tag == SMDX_LABEL and a.text:
                    label = a.text
                elif a.tag == SMDX_DESCRIPTION and a.text:
                    desc = a.text
                elif a.tag == SMDX_NOTES and a.text:
                    notes = a.text

            point_def = fixed_points_map.get(pid)
            if point_def is not None:
                if label:
                    point_def[mdef.LABEL] = label
                if desc:
                    point_def[mdef.DESCRIPTION] = desc
                if notes:
                    point_def[mdef.DETAIL] = notes
            point_def = repeating_points_map.get(pid)
            if point_def is not None:
                if label:
                    point_def[mdef.LABEL] = label
                if desc:
                    point_def[mdef.DESCRIPTION] = desc
                if notes:
                    point_def[mdef.DETAIL] = notes

    model_def = {'id': mid, 'group': fixed_def}
    return model_def