Esempio n. 1
0
    def from_smdx(self, element):

        smdx_data = ''

        for m in element.findall(smdx.SMDX_MODEL):
            if True:
                self.id = int(m.attrib.get(smdx.SMDX_ATTR_ID))
                self.len = m.attrib.get(smdx.SMDX_ATTR_LEN)
                self.name = m.attrib.get(smdx.SMDX_ATTR_NAME)
                if self.name is None:
                    self.name = 'model_' + str(self.id)

                if self.len is None:
                    raise SunSpecError('Module len error')
                self.len = int(self.len)

                for b in m.findall(smdx.SMDX_BLOCK):
                    block = BlockType(model_type=self)
                    block.from_smdx(b)

                    if block.type == suns.SUNS_BLOCK_FIXED:
                        if self.fixed_block is None:
                            self.fixed_block = block
                        else:
                            raise SunSpecError(
                                'Duplicate fixed block type definition')
                    elif block.type == suns.SUNS_BLOCK_REPEATING:
                        if self.repeating_block is None:
                            self.repeating_block = block
                        else:
                            raise SunSpecError(
                                'Duplicate repeating block type definition')
                break
            else:
                raise SunSpecError('Unexpected smdx element: %s' % m.tag)

        for s in element.findall(smdx.SMDX_STRINGS):
            if s.attrib.get(smdx.SMDX_ATTR_ID) == str(self.id):
                m = s.find(smdx.SMDX_MODEL)
                if m is not None:
                    for e in m.findall('*'):
                        if e.tag == smdx.SMDX_LABEL:
                            self.label = e.text
                        elif e.tag == smdx.SMDX_DESCRIPTION:
                            self.description = e.text
                        elif e.tag == smdx.SMDX_NOTES:
                            self.notes = e.text
                for e in s.findall(smdx.SMDX_POINT):
                    pid = e.attrib.get(smdx.SMDX_ATTR_ID)
                    point_type = None
                    if self.fixed_block is not None:
                        point_type = self.fixed_block.points.get(pid)
                    if point_type is None and self.repeating_block is not None:
                        point_type = self.repeating_block.points.get(pid)
                    if point_type:
                        point_type.from_smdx(e, strings=True)

        if self.fixed_block is None:
            self.fixed_block = BlockType(suns.SUNS_BLOCK_FIXED,
                                         model_type=self)
Esempio n. 2
0
    def from_smdx(self, element):
        """ Sets the block type attributes based on an element tree block type
        element contained in an SMDX model definition.

        Parameters:

            element :
                Element Tree block type element.
        """

        btype = element.attrib.get(smdx.SMDX_ATTR_TYPE,
                                   smdx.SMDX_ATTR_TYPE_FIXED)

        if btype != smdx.SMDX_ATTR_TYPE_FIXED and btype != smdx.SMDX_ATTR_TYPE_REPEATING:
            raise SunSpecError('Invalid block type')

        self.type = smdx.smdx_block_types.get(btype)
        self.len = element.attrib.get(smdx.SMDX_ATTR_LEN)
        if self.len is None:
            raise SunSpecError('Block len error')
        self.name = element.attrib.get(smdx.SMDX_ATTR_NAME)
        if self.name is None:
            self.name = self.type

        # process points
        for e in element.findall(smdx.SMDX_POINT):
            pt = PointType(block_type=self)
            pt.from_smdx(e)

            if self.points.get(pt.id) is not None:
                ET.dump(e)
                raise SunSpecError('Duplicate point definition: %s' % (pt.id))

            self.points_list.append(pt)
            self.points[pt.id] = pt
Esempio n. 3
0
    def from_pics(self, element):

        # update index if present
        self.index = element.attrib.get(pics.PICS_ATTR_INDEX, self.index)

        for b in element.findall('*'):
            if b.tag != pics.PICS_BLOCK:
                raise SunSpecError("Unexpected '%s' element in '%s' element" %
                                   (b.tag, element.tag))
            block_type = pics.pics_block_types.get(
                b.attrib.get(pics.PICS_ATTR_TYPE, pics.PICS_TYPE_FIXED))
            if block_type is None:
                raise SunSpecError('Unknown block type')
            if block_type == suns.SUNS_BLOCK_FIXED:
                if len(self.blocks) > 0:
                    self.blocks[0].from_pics(b)
            elif block_type == suns.SUNS_BLOCK_REPEATING:
                block_index = b.attrib.get(pics.PICS_ATTR_INDEX)
                # if no index specified, apply to all repeating blocks
                if block_index is None:
                    if len(self.blocks) > 1:
                        for block in self.blocks[1:]:
                            block.from_pics(b)
                else:
                    block_index = int(block_index)
                    if len(self.blocks) < block_index:
                        raise SunSpecError('Block index out of range: %s' %
                                           (str(block_index)))
                    self.blocks[block_index].from_pics(b)
            else:
                raise SunSpecError('Internal block type error')
Esempio n. 4
0
    def from_pics(self, element):
        """Sets the block contents based on an element tree model type element
        contained in a SunSpec PICS document.

        Parameters:

            element :
                Element Tree model element.
        """

        for p in element.findall('*'):
            if p.tag != pics.PICS_POINT:
                raise SunSpecError("Unexpected '%s' element in '%s' element" %
                                   (p.tag, element.tag))
            pid = p.attrib.get(pics.PICS_ATTR_ID)
            point = self.points.get(pid)
            if point is None:
                point = self.points_sf.get(pid)
            if point is not None:
                point.from_pics(p)

        # resolve scale factor values in points, must be done after all points in block are read
        for point in self.points_list:
            if point.sf_point is not None:
                point.value_sf = point.sf_point.value_base
Esempio n. 5
0
    def from_smdx(self, element, strings=False):

        for e in element.findall('*'):
            if e.tag == smdx.SMDX_LABEL:
                self.label = e.text
            elif e.tag == smdx.SMDX_DESCRIPTION:
                self.description = e.text
            elif e.tag == smdx.SMDX_NOTES:
                self.notes = e.text
            elif e.tag == smdx.SMDX_SYMBOL:
                sid = e.attrib.get(smdx.SMDX_ATTR_ID)
                symbol = self.block_type.model_type.symbol_get(sid)
                if symbol is None:
                    symbol = Symbol()
                    symbol.from_smdx(e, strings)
                    self.block_type.model_type.symbol_add(symbol)
                if self.symbol_get(sid) is None:
                    self.symbols.append(symbol)
                symbol.from_smdx(e, strings)

        if strings is False:
            self.id = element.attrib.get(smdx.SMDX_ATTR_ID)
            self.offset = int(element.attrib.get(smdx.SMDX_ATTR_OFFSET))
            ptype = element.attrib.get(smdx.SMDX_ATTR_TYPE)
            plen = element.attrib.get(smdx.SMDX_ATTR_LEN)
            mandatory = element.attrib.get(smdx.SMDX_ATTR_MANDATORY,
                                           smdx.SMDX_MANDATORY_FALSE)
            access = element.attrib.get(smdx.SMDX_ATTR_ACCESS,
                                        smdx.SMDX_ACCESS_R)
            self.units = element.attrib.get(smdx.SMDX_ATTR_UNITS)

            if self.id is None:
                raise SunSpecError('Missing point id attribute')
            if self.offset is None:
                raise SunSpecError('Missing offset attribute for point: %s' %
                                   self.id)
            if ptype is None:
                raise SunSpecError('Missing type attribute for point: %s' %
                                   self.id)
            if ptype == smdx.SMDX_TYPE_STRING and plen is None:
                raise SunSpecError('Missing len attribute for point: %s' %
                                   self.id)

            self.type = smdx.smdx_point_types.get(ptype)
            if self.type is None:
                raise SunSpecError('Unknown point type: %s' % ptype)
            self.mandatory = smdx.smdx_mandatory_types.get(mandatory)
            if self.mandatory is None:
                raise SunSpecError('Unknown mandatory type: %s' % mandatory)
            self.access = smdx.smdx_access_types.get(access)
            if self.access is None:
                raise SunSpecError('Unknown access type: %s' % access)
            self.sf = element.attrib.get(smdx.SMDX_ATTR_SF)

            info = suns.suns_point_type_info.get(self.type)

            if info is not None:
                self.len, self.is_impl, self.data_to, self.to_data, self.to_value, self.value_default = info
                if plen is not None:
                    self.len = int(plen)
Esempio n. 6
0
def model_type_get(model_id):

    global file_pathlist
    global model_types

    model_type = model_types.get(str(model_id))
    if model_type is None:
        smdx_data = ''
        # create model file name
        filename = smdx.model_id_to_filename(model_id)

        # check in file path list if set
        if file_pathlist is not None:
            try:
                smdx_data = file_pathlist.read(filename)
            except NameError:
                pass

        if not smdx_data:
            if not os.path.exists(filename):
                filename = os.path.join(model_type_path_default, filename)

            if os.path.exists(filename):
                try:
                    f = open(filename, 'r')
                    smdx_data = f.read()
                    f.close()
                except Exception as e:
                    raise SunSpecError('Error loading model {} at {}: {}'.format(model_id, filename, str(e)))

        if smdx_data:
            root = ET.fromstring(smdx_data)

            # load model type
            try:
                model_type = ModelType()
                model_type.from_smdx(root)
                model_types[model_type.id] = model_type
            except Exception as e:
                raise SunSpecError('Error loading model {} at {}: {}'.format(model_id, filename, str(e)))
        else:
            raise SunSpecError('Model file for model %s not found' % (str(model_id)))

    return model_type
Esempio n. 7
0
    def from_smdx(self, element, strings=False):

        for e in element.findall('*'):
            if e.tag == smdx.SMDX_LABEL:
                self.label = e.text
            elif e.tag == smdx.SMDX_DESCRIPTION:
                self.description = e.text
            elif e.tag == smdx.SMDX_NOTES:
                self.notes = e.text

        if strings is False:
            self.id = element.attrib.get(smdx.SMDX_ATTR_ID)
            self.value = element.text
            if self.id is None:
                raise SunSpecError('Missing point id attribute')
Esempio n. 8
0
    def from_pics(self, element):
        """ Sets the model contents based on an element tree model type element
        contained in a SunSpec PICS document.

        Parameters:

            element :
                Element Tree model element.
        """

        # update index if present
        self.index = element.attrib.get(pics.PICS_ATTR_INDEX, self.index)

        for b in element.findall('*'):
            if b.tag != pics.PICS_BLOCK:
                raise SunSpecError("Unexpected '{}' element in '{}' element".format(b.tag, element.tag))
            block_type = pics.pics_block_types.get(b.attrib.get(pics.PICS_ATTR_TYPE, pics.PICS_TYPE_FIXED))
            if block_type is None:
                raise SunSpecError('Unknown block type')
            if block_type == suns.SUNS_BLOCK_FIXED:
                if len(self.blocks) > 0:
                    self.blocks[0].from_pics(b)
            elif block_type == suns.SUNS_BLOCK_REPEATING:
                block_index = b.attrib.get(pics.PICS_ATTR_INDEX)
                # if no index specified, apply to all repeating blocks
                if block_index is None:
                    if len(self.blocks) > 1:
                        for block in self.blocks[1:]:
                            block.from_pics(b)
                else:
                    block_index = int(block_index)
                    if len(self.blocks) < block_index:
                        raise SunSpecError('Block index out of range: %s' % (str(block_index)))
                    self.blocks[block_index].from_pics(b)
            else:
                raise SunSpecError('Internal block type error')
Esempio n. 9
0
    def from_pics(self, element):

        for p in element.findall('*'):
            if p.tag != pics.PICS_POINT:
                raise SunSpecError("Unexpected '%s' element in '%s' element" % (p.tag, element.tag))
            pid = p.attrib.get(pics.PICS_ATTR_ID)
            point = self.points.get(pid)
            if point is None:
                point = self.points_sf.get(pid)
            if point is not None:
                point.from_pics(p)

        # resolve scale factor values in points, must be done after all points in block are read
        for point in self.points_list:
            if point.sf_point is not None:
                point.value_sf = point.sf_point.value_base
Esempio n. 10
0
    def from_pics(self, element=None, filename=None, pathlist=None):
        """The PICS information for the device can be either an Element Tree
        element for a device from a document already being processed or the file
        name of document in the file system. Populates the device based on the
        elements within the device element.

        Parameters:

            element :
                Element Tree device element.

            filename :
                File name of the PICS document.

            pathlist :
                Pathlist object containing alternate paths to the PICS document.
        """

        global file_pathlist

        pics_data = ''

        try:
            if element is None:
                # try supplied path list
                if pathlist is not None:
                    try:
                        pics_data = pathlist.read(filename)
                    except NameError:
                        pass

                # try device file path list
                if not pics_data and file_pathlist is not None:
                    try:
                        pics_data = file_pathlist.read(filename)
                    except NameError:
                        pass

                # try local directory
                if not pics_data:
                    f = open(filename, 'r')
                    pics_data = f.read()
                    f.close()

                root = ET.fromstring(pics_data)
                if root.tag != pics.PICS_ROOT:
                    raise SunSpecError("Unexpected root element: %s" %
                                       (root.tag))

                d = root.find(pics.PICS_DEVICE)
                if d is None:
                    raise SunSpecError(
                        "No '%s' elements found in '%s' element" %
                        (pics.PICS_DEVICE, root.tag))
            else:
                d = element
            if d.tag != pics.PICS_DEVICE:
                raise SunSpecError("Unexpected device tag: '%s'" % (d.tag))
            self.base_addr = d.attrib.get(pics.PICS_ATTR_BASE_ADDR,
                                          pics.PICS_BASE_ADDR_DEFAULT)
            addr = self.base_addr + 2

            for m in d.findall('*'):
                if m is None:
                    raise SunSpecError(
                        "No '%s' elements found in '%s' element" %
                        (pics.PICS_MODEL, d.tag))
                if m.tag != pics.PICS_MODEL:
                    raise SunSpecError(
                        "Unexpected '%s' element in '%s' element" %
                        (m.tag, d.tag))

                model_id = m.attrib.get(pics.PICS_ATTR_ID)
                if model_id is None:
                    raise SunSpecError('Module id error')
                model_len = m.attrib.get(pics.PICS_ATTR_LEN)
                if model_len is not None:
                    # raise SunSpecError('Module len error in model %d' % (model_id))
                    model_len = int(model_len)

                # move address past model id and length (even though address is not real in the case)
                model = Model(self, model_id, addr + 2, model_len)
                try:
                    model.load()
                except Exception, e:
                    model.load_error = str(e)
                model.from_pics(m)
                self.add_model(model)

                addr += model.len + 2

        except Exception, e:
            raise SunSpecError('Error loading PICS: %s' % str(e))
Esempio n. 11
0
    def load(self, block_class=Block, point_class=Point):
        """Loads the model instance with blocks and points based on the SunSpec
        model type definition.

        Parameters:

            block_class :
                Block class to use to create block instances.

            point_class :
                Point class to use to create point instances.
        """

        last_read_addr = self.addr
        self.read_blocks.append(last_read_addr)

        self.model_type = model_type_get(self.id)

        if self.model_type is not None:
            if self.len == 0:
                self.len = self.model_type.len
            end_addr = self.addr + self.len

            index = 0
            # model type always has a fixed block defined
            block_type = self.model_type.fixed_block
            block_addr = self.addr
            block_len = int(block_type.len)
            # adjustment for legacy common model len = 65
            if self.id == 1 and self.len == 65:
                block_len = self.len

            # while another block
            while end_addr >= block_addr + block_len:
                block = block_class(self, block_addr, block_len, block_type,
                                    index)
                self.blocks.append(block)

                for point_type in block_type.points_list:
                    if point_type.type != suns.SUNS_TYPE_PAD:
                        point_addr = int(block_addr) + int(point_type.offset)
                        point = point_class(block, point_type, str(point_addr))
                        if point_addr + point.point_type.len - last_read_addr > MAX_READ_COUNT:
                            last_read_addr = point_addr
                            self.read_blocks.append(last_read_addr)
                        if point_type.type == suns.SUNS_TYPE_SUNSSF:
                            block.points_sf[point_type.id] = point
                        else:
                            block.points_list.append(point)
                            block.points[point_type.id] = point

                # resolve scale factor addresses for repeating block
                for point in block.points_list:
                    if point.point_type.sf is not None and point.sf_point is None:
                        # check for constant scale factor
                        try:
                            sf_value = int(point.point_type.sf)
                            point.sf_point = ScaleFactor(sf_value)
                        except Exception:
                            pass
                        # try local repeating block first
                        if point.sf_point is None:
                            point.sf_point = block.points_sf.get(
                                point.point_type.sf)
                        if point.sf_point is None:
                            # if repeating block, try fixed block
                            if index > 0:
                                point.sf_point = self.blocks[0].points_sf.get(
                                    point.point_type.sf)
                        if point.sf_point is None:
                            # ### what state should model be left in on exception
                            raise SunSpecError(
                                'Unable to resolve scale factor point %s for point %s in model %s'
                                % point.point_type.sf, point.point_type.pid,
                                self.id)

                block_addr += block_len
                block_type = self.model_type.repeating_block
                if block_type is None:
                    ### check for extra registers?
                    break
                index += 1
                block_len = int(block_type.len)
        else:
            raise SunSpecError('Unknown model type - id: %s' % str(self.id))

        # expose fixed block points at model level if present
        try:
            self.points_list = self.blocks[0].points_list
            self.points = self.blocks[0].points
            self.points_sf = self.blocks[0].points_sf
        except IndexError:
            pass
Esempio n. 12
0
                    raise SunSpecError('Error loading model %s at %s: %s' %
                                       (model_id, filename, str(e)))

        if smdx_data:
            root = ET.fromstring(smdx_data)

            # load model type
            try:
                model_type = ModelType()
                model_type.from_smdx(root)
                model_types[model_type.id] = model_type
            except Exception, e:
                raise SunSpecError('Error loading model %s at %s: %s' %
                                   (model_id, filename, str(e)))
        else:
            raise SunSpecError('Model file for model %s not found' %
                               (str(model_id)))

    return model_type


class ModelType(object):
    """
    Parameters:

        mid :
            Model id that identifies a specific SunSpec model type definition.

    Attributes:

        id
            Model id that identifies a specific SunSpec model type definition.
Esempio n. 13
0
    def from_pics(self, element=None, filename=None, pathlist=None):

        global file_pathlist

        pics_data = ''

        try:
            if element is None:
                # try supplied path list
                if pathlist is not None:
                    try:
                        pics_data = pathlist.read(filename)
                    except NameError:
                        pass

                # try device file path list
                if not pics_data and file_pathlist is not None:
                    try:
                        pics_data = file_pathlist.read(filename)
                    except NameError:
                        pass

                # try local directory
                if not pics_data:
                    f = open(filename, 'r')
                    pics_data = f.read()
                    f.close()

                root = ET.fromstring(pics_data)
                if root.tag != pics.PICS_ROOT:
                    raise SunSpecError("Unexpected root element: %s" %
                                       (root.tag))

                d = root.find(pics.PICS_DEVICE)
                if d is None:
                    raise SunSpecError(
                        "No '%s' elements found in '%s' element" %
                        (pics.PICS_DEVICE, root.tag))
            else:
                d = element
            if d.tag != pics.PICS_DEVICE:
                raise SunSpecError("Unexpected device tag: '%s'" % (d.tag))
            self.base_addr = d.attrib.get(pics.PICS_ATTR_BASE_ADDR,
                                          pics.PICS_BASE_ADDR_DEFAULT)
            addr = self.base_addr + 2

            for m in d.findall('*'):
                if m is None:
                    raise SunSpecError(
                        "No '%s' elements found in '%s' element" %
                        (pics.PICS_MODEL, d.tag))
                if m.tag != pics.PICS_MODEL:
                    raise SunSpecError(
                        "Unexpected '%s' element in '%s' element" %
                        (m.tag, d.tag))

                model_id = m.attrib.get(pics.PICS_ATTR_ID)
                if model_id is None:
                    raise SunSpecError('Module id error')
                model_len = m.attrib.get(pics.PICS_ATTR_LEN)
                if model_len is not None:
                    # raise SunSpecError('Module len error in model %d' % (model_id))
                    model_len = int(model_len)

                # move address past model id and length (even though address is not real in the case)
                model = Model(self, model_id, addr + 2, model_len)
                try:
                    model.load()
                except Exception, e:
                    model.load_error = str(e)
                model.from_pics(m)
                self.add_model(model)

                addr += model.len + 2

        except Exception, e:
            raise SunSpecError('Error loading PICS: %s' % str(e))