class SwapParam: """ Generic SWAP parameter, integrated into a SWAP register """ def getRegAddress(self): """ Return register address of the current parameter @return Register address """ return self.register.getAddress() def getRegId(self): """ Return register ID of the current parameter @return Register ID """ return self.register.id def update(self): """ Update parameter's value, posibly after a change in its parent register """ self.valueChanged = False if self.register is None: raise SwapException("Register not specified for current endpoint") return # Current register value converted to list lstRegVal = self.register.value.toList() # Total bits to be copied indexReg = self.bytePos shiftReg = 7 - self.bitPos bitsToCopy = self.byteSize * 8 + self.bitSize # Current parameter value in list format lstParamVal = self.value.toList() if len(lstParamVal) == 0: return # Keep old value oldParamVal = self.value.clone() indexParam = 0 shiftParam = self.bitSize - 1 if shiftParam < 0: shiftParam = 7 for i in range(bitsToCopy): if indexReg >= len(lstRegVal): break if (lstRegVal[indexReg] >> shiftReg) & 0x01 == 0: mask = ~(1 << shiftParam) lstParamVal[indexParam] &= mask else: mask = 1 << shiftParam lstParamVal[indexParam] |= mask shiftReg -= 1 shiftParam -= 1 # Register byte over? if shiftReg < 0: indexReg += 1 shiftReg = 7 # Parameter byte over? if shiftParam < 0: indexParam += 1 shiftParam = 7 # Did the value change? if not self.value.isEqual(oldParamVal): self.valueChanged = True # Update time stamp self.lastupdate = time.time() def setValue(self, value): """ Set parameter value @param value: New parameter value """ # Convert to SwapValue if value.__class__ is SwapValue: # Incorrect length? if self.value.getLength() != value.getLength(): return self.value = value else: # Byte length length = self.byteSize if self.bitSize > 0: length += 1 if type(value) is list: res = value elif type(value) in [str, unicode]: if self.type == SwapType.NUMBER: try: # Possible integer number res = int(value) except ValueError: try: # Possible float number res = float(value) except ValueError: raise SwapException(value + " is not a valid numeric value for " + self.name) elif self.type == SwapType.BINARY: if value.lower() in ["on", "open", "1", "true", "enabled"]: res = 1 else: res = 0 else: # SwapType.STRING res = value else: res = value if type(res) in [int, float]: if self.unit is not None: res -= self.unit.offset res /= self.unit.factor # Convert to integer res = int(res) self.value = SwapValue(res, length) # Update current value self.value = SwapValue(res, length) # Update time stamp self.lastupdate = time.time() # Update register value self.register.update() def getValueInAscii(self): """ Return value in ASCII string format @return Value in ASCII format """ if self.type == SwapType.NUMBER: val = self.value.toInteger() # Add units if self.unit is not None: if self.unit.calc is not None: oper = self.unit.calc.replace("${val}", str(val)) try: val = eval("math." + oper) except ValueError as ex: raise SwapException("Math exception for " + oper + ". " + str(ex)) strVal = str(val * self.unit.factor + self.unit.offset) else: strVal = str(val) elif self.type == SwapType.BINARY: strVal = self.value.toAscii() if strVal == "1": strVal = "on" elif strVal == "0": strVal = "off" else: strVal = self.value.toAsciiStr() return strVal def setUnit(self, strunit): """ Set unit for the current parameter @param strunit: new unit in string format """ if self.lstunits is None: raise SwapException("Parameter " + self.name + " does not support units") for unit in self.lstunits: if unit.name == strunit: self.unit = unit return raise SwapException("Unit " + strunit + " not found") def __init__(self, register=None, pType=SwapType.NUMBER, direction=SwapType.INPUT, name="", position="0", size="1", default=None, verif=None, units=None): """ Class constructor @param register: Register containing this parameter @param pType: Type of SWAP endpoint (see SwapDefs.SwapType) @param direction: Input or output (see SwapDefs.SwapType) @param name: Short description about the parameter @param position: Position in bytes.bits within the parent register @param size: Size in bytes.bits @param default: Default value in string format @param verif: Verification string @param units: List of units """ ## Parameter name self.name = name ## Register where the current parameter belongs to self.register = register ## Data type (see SwapDefs.SwapType for more details) self.type = pType ## Direction (see SwapDefs.SwapType for more details) self.direction = direction ## Position (in bytes) of the parameter within the register self.bytePos = 0 ## Position (in bits) after bytePos self.bitPos = 0 # Get true positions dot = position.find('.') if dot > -1: self.bytePos = int(position[:dot]) self.bitPos = int(position[dot+1:]) else: self.bytePos = int(position) ## Size (in bytes) of the parameter value self.byteSize = 1 ## Size in bits of the parameter value after byteSize self.bitSize = 0 # Get true sizes dot = size.find('.') if dot > -1: self.byteSize = int(size[:dot]) self.bitSize = int(size[dot+1:]) else: self.byteSize = int(size) ## Current value self.value = None ## Time stamp of the last update self.lastupdate = None ## List of units self.lstunits = units ## Selected unit self.unit = None if self.lstunits is not None and len(self.lstunits) > 0: self.unit = self.lstunits[0] # Set initial value if default is not None: self.setValue(default) ## Flag that tells us whether this parameter changed its value during the last update or not self.valueChanged = False ## Verification string. This can be a macro or a regular expression self.verif = verif ## Display this parameter from master app self.display = True
class SwapParam: """ Generic SWAP parameter, integrated into a SWAP register """ def getRegAddress(self): """ Return register address of the current parameter @return Register address """ return self.register.getAddress() def getRegId(self): """ Return register ID of the current parameter @return Register ID """ return self.register.id def update(self): """ Update parameter's value, posibly after a change in its parent register """ self.valueChanged = False if self.register is None: raise SwapException("Register not specified for current endpoint") return # Keep old value oldParamVal = self.value.clone() # This is a particular case: endpoint is an ASCII string taking all the # register space if self.type in [SwapType.STRING, SwapType.BSTRING]: self.value = self.register.value else: # Current register value converted to list lstRegVal = self.register.value.toList() # Total bits to be copied indexReg = self.bytePos shiftReg = 7 - self.bitPos bitsToCopy = self.byteSize * 8 + self.bitSize # Current parameter value in list format lstParamVal = self.value.toList() if len(lstParamVal) == 0: return indexParam = 0 shiftParam = self.bitSize - 1 if shiftParam < 0: shiftParam = 7 for i in range(bitsToCopy): if indexReg >= len(lstRegVal): break if (lstRegVal[indexReg] >> shiftReg) & 0x01 == 0: mask = ~(1 << shiftParam) lstParamVal[indexParam] &= mask else: mask = 1 << shiftParam lstParamVal[indexParam] |= mask shiftReg -= 1 shiftParam -= 1 # Register byte over? if shiftReg < 0: indexReg += 1 shiftReg = 7 # Parameter byte over? if shiftParam < 0: indexParam += 1 shiftParam = 7 # Did the value change? if not self.value.isEqual(oldParamVal): self.valueChanged = True # Update time stamp self.lastupdate = time.time() def setValue(self, value): """ Set parameter value @param value: New parameter value """ # Convert to SwapValue if value.__class__ is SwapValue: # Incorrect length? if self.value.getLength() != value.getLength(): return self.value = value else: # Byte length length = self.byteSize if self.bitSize > 0: length += 1 if type(value) is list: res = value elif type(value) in [str, unicode]: if self.type == SwapType.NUMBER: try: # Possible integer number res = int(value) except ValueError: try: # Possible float number res = float(value) except ValueError: raise SwapException(value + " is not a valid numeric value for " + self.name) elif self.type == SwapType.BINARY: if value.lower() in ["on", "open", "1", "true", "enabled"]: res = 1 else: res = 0 else: # SwapType.STRING, SwapType.BSTRING res = value else: res = value if type(res) in [int, float]: if self.unit is not None: res -= self.unit.offset res /= self.unit.factor # Convert to integer res = int(res) self.value = SwapValue(res, length) # Update current value self.value = SwapValue(res, length) # Update time stamp self.lastupdate = time.time() # Update register value self.register.update() def getValueInAscii(self): """ Return value in ASCII string format @return Value in ASCII format """ if self.type == SwapType.NUMBER: val = self.value.toInteger() # Add units if self.unit is not None: if self.unit.calc is not None: oper = self.unit.calc.replace("${val}", str(val)) try: val = eval("math." + oper) except ValueError as ex: raise SwapException("Math exception for " + oper + ". " + str(ex)) strVal = str(val * self.unit.factor + self.unit.offset) else: strVal = str(val) elif self.type == SwapType.BINARY: strVal = self.value.toAscii() if strVal == "1": strVal = "on" elif strVal == "0": strVal = "off" elif self.type == SwapType.BSTRING: strVal = self.value.toAsciiHex() else: strVal = self.value.toAsciiStr() return strVal def setUnit(self, strunit): """ Set unit for the current parameter @param strunit: new unit in string format """ if self.lstunits is None: raise SwapException("Parameter " + self.name + " does not support units") for unit in self.lstunits: if unit.name == strunit: self.unit = unit return raise SwapException("Unit " + strunit + " not found") def __init__(self, register=None, pType=SwapType.NUMBER, direction=SwapType.INPUT, name="", position="0", size="1", default=None, verif=None, units=None): """ Class constructor @param register: Register containing this parameter @param pType: Type of SWAP endpoint (see SwapDefs.SwapType) @param direction: Input or output (see SwapDefs.SwapType) @param name: Short description about the parameter @param position: Position in bytes.bits within the parent register @param size: Size in bytes.bits @param default: Default value in string format @param verif: Verification string @param units: List of units """ ## Parameter name self.name = name ## Register where the current parameter belongs to self.register = register ## Data type (see SwapDefs.SwapType for more details) self.type = pType ## Direction (see SwapDefs.SwapType for more details) self.direction = direction ## Position (in bytes) of the parameter within the register self.bytePos = 0 ## Position (in bits) after bytePos self.bitPos = 0 # Get true positions dot = position.find('.') if dot > -1: self.bytePos = int(position[:dot]) self.bitPos = int(position[dot+1:]) else: self.bytePos = int(position) ## Size (in bytes) of the parameter value self.byteSize = 1 ## Size in bits of the parameter value after byteSize self.bitSize = 0 # Get true sizes dot = size.find('.') if dot > -1: self.byteSize = int(size[:dot]) self.bitSize = int(size[dot+1:]) else: self.byteSize = int(size) ## Current value self.value = None ## Time stamp of the last update self.lastupdate = None ## List of units self.lstunits = units ## Selected unit self.unit = None if self.lstunits is not None and len(self.lstunits) > 0: self.unit = self.lstunits[0] # Set initial value if default is not None: self.setValue(default) ## Flag that tells us whether this parameter changed its value during the last update or not self.valueChanged = False ## Verification string. This can be a macro or a regular expression self.verif = verif ## Display this parameter from master app self.display = True