def set_tags(self): typenames = { "BOOL": (parser.BOOL, 0, lambda v: bool(v)), "INT": (parser.INT, 0, lambda v: int(v)), "DINT": (parser.DINT, 0, lambda v: long(v)), "SINT": (parser.SINT, 0, lambda v: int(v)), "REAL": (parser.REAL, 0.0, lambda v: float(v)), "SSTRING": (parser.SSTRING, '', lambda v: str(v)), "STRING": (parser.STRING, '', lambda v: str(v)), } for t in self.config.dtags: tag_name = t.name tag_type = t.type tag_size = t.size assert tag_type in typenames, "Invalid tag type; must be one of %r" % list(typenames) tag_class, tag_default, f = typenames[tag_type] tag_value = f(t.value) tag_address = t.addr logger.debug("tag address: %s", tag_address) path, attribute = None, None if tag_address: # Resolve the @cls/ins/att, and optionally [elm] or /elm segments, elm, cnt = device.parse_path_elements('@' + tag_address) assert not cnt or cnt == 1, \ "A Tag may be specified to indicate a single element: %s" % (tag_address) path = {'segment': segments} cls, ins, att = device.resolve(path, attribute=True) assert ins > 0, "Cannot specify the Class' instance for a tag's address" elm = device.resolve_element(path) # Look thru defined tags for one assigned to same cls/ins/att (maybe different elm); # must be same type/size. for tn, te in dict.items(self.tags): if not te['path']: continue # Ignore tags w/o pre-defined path... if device.resolve(te['path'], attribute=True) == (cls, ins, att): assert te.attribute.parser.__class__ is tag_class and len(te.attribute) == tag_size, \ "Incompatible Attribute types for tags %r and %r" % (tn, tag_name) attribute = te.attribute break if not attribute: # No Attribute found attribute = device.Attribute(tag_name, tag_class, default = (tag_value if tag_size == 1 else [tag_value] * tag_size)) # Ready to create the tag and its Attribute (and error code to return, if any). If tag_size # is 1, it will be a scalar Attribute. Since the tag_name may contain '.', we don't want # the normal dotdict.__setitem__ resolution to parse it; use plain dict.__setitem__. logger.debug("Creating tag: %-14s%-10s %10s[%4d]", tag_name, '@' + tag_address if tag_address else '', attribute.parser.__class__.__name__, len(attribute)) tag_entry = cpppo.dotdict() tag_entry.attribute = attribute # The Attribute (may be shared by multiple tags) tag_entry.path = path # Desired Attribute path (may include element), or None tag_entry.error = 0x00 dict.__setitem__(self.tags, tag_name, tag_entry)
def set_tags(self): typenames = { "BOOL": (parser.BOOL, 0, lambda v: bool(v)), "INT": (parser.INT, 0, lambda v: int(v)), "DINT": (parser.DINT, 0, lambda v: int(v)), "SINT": (parser.SINT, 0, lambda v: int(v)), "REAL": (parser.REAL, 0.0, lambda v: float(v)), "SSTRING": (parser.SSTRING, '', lambda v: str(v)), "STRING": (parser.STRING, '', lambda v: str(v)), } for t in self.config.dtags: tag_name = t.name tag_type = t.type tag_size = t.size assert tag_type in typenames, "Invalid tag type; must be one of %r" % list(typenames) tag_class, tag_default, f = typenames[tag_type] tag_value = f(t.value) tag_address = t.addr logger.debug("tag address: %s", tag_address) path, attribute = None, None if tag_address: # Resolve the @cls/ins/att, and optionally [elm] or /elm segments, elm, cnt = device.parse_path_elements('@' + tag_address) assert not cnt or cnt == 1, \ "A Tag may be specified to indicate a single element: %s" % (tag_address) path = {'segment': segments} cls, ins, att = device.resolve(path, attribute=True) assert ins > 0, "Cannot specify the Class' instance for a tag's address" elm = device.resolve_element(path) # Look thru defined tags for one assigned to same cls/ins/att (maybe different elm); # must be same type/size. for tn, te in dict.items(self.tags): if not te['path']: continue # Ignore tags w/o pre-defined path... if device.resolve(te['path'], attribute=True) == (cls, ins, att): assert te.attribute.parser.__class__ is tag_class and len(te.attribute) == tag_size, \ "Incompatible Attribute types for tags %r and %r" % (tn, tag_name) attribute = te.attribute break if not attribute: # No Attribute found attribute = device.Attribute(tag_name, tag_class, default = (tag_value if tag_size == 1 else [tag_value] * tag_size)) # Ready to create the tag and its Attribute (and error code to return, if any). If tag_size # is 1, it will be a scalar Attribute. Since the tag_name may contain '.', we don't want # the normal dotdict.__setitem__ resolution to parse it; use plain dict.__setitem__. logger.debug("Creating tag: %-14s%-10s %10s[%4d]", tag_name, '@' + tag_address if tag_address else '', attribute.parser.__class__.__name__, len(attribute)) tag_entry = cpppo.dotdict() tag_entry.attribute = attribute # The Attribute (may be shared by multiple tags) tag_entry.path = path # Desired Attribute path (may include element), or None tag_entry.error = 0x00 dict.__setitem__(self.tags, tag_name, tag_entry)