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
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)))
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
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
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