def dyn_attr(self): self.dyn_attrs = getattr(self, 'dyn_attrs', []) self.info('dyn_attr(%s)' % self.dyn_attrs) for l, n in product('VPI', '1234'): if l + n not in self.dyn_attrs: self.info('Adding attribute: %s' % (l + n)) unit, frmt = { 'V': ('V', '%d'), 'P': ('mbar', '%g'), 'I': ('mA', '%g') }[l] attrib = PyTango.Attr(l + n, PyTango.DevDouble, PyTango.AttrWriteType.READ) props = PyTango.UserDefaultAttrProp() props.set_format(frmt), props.set_unit(unit) attrib.set_default_properties(props) self.add_attribute(attrib, self.read_dyn_attr, None, self.is_Attr_allowed) self.thread.append(l + n, period=self.Refresh) for a in ('Model', 'ErrorCode', 'ModeLocal'): self.info('Adding attribute (%d s): %s' % (self.Refresh * 5, a)) attrib = PyTango.Attr(a, PyTango.DevString, PyTango.AttrWriteType.READ) self.add_attribute(attrib, self.read_dyn_attr, None, self.is_Attr_allowed) self.thread.append(a, period=self.Refresh * 5)
def initialize_dynamic_attributes(self): """ Initialize dynamic attributes """ if self.chiller_type == self.POLYSCIENCE: # Add temperature attribute attr = PT.Attr("Temperature", PT.DevDouble, PT.AttrWriteType.READ) attr_prop = PT.UserDefaultAttrProp() attr_prop.label = "Temperature" attr_prop.format = "%.1f" attr_prop.unit = "°C" attr.set_default_properties(attr_prop) attr.set_change_event(True, False) self.add_attribute(attr, self.read_Temperature) # Subscribe events self.dev.subscribe_event("Temperature", PT.EventType.CHANGE_EVENT, self.event_callback) self.dev.subscribe_event("State", PT.EventType.CHANGE_EVENT, self.event_callback) else: # Subscribe events self.dev.subscribe_event("State", PT.EventType.CHANGE_EVENT, self.event_callback) # Subscribe events from water valve self.water.subscribe_event("State", PT.EventType.CHANGE_EVENT, self.event_callback) self.water.subscribe_event("WaterFlow", PT.EventType.CHANGE_EVENT, self.event_callback)
def add_RegulationTuneable(self): @PS.AttrExc def read_RegulationTuneable(inst, attr): attr.set_value(self.writeable) @PS.AttrExc def write_RegulationTuneable(inst, attr): self.writeable = attr.get_write_value() inst.push_change_event('RegulationTuneable', self.writeable) attr = Tg.Attr('RegulationTuneable', Tg.DevBoolean, Tg.READ_WRITE) self.impl.add_attribute(attr, r_meth=read_RegulationTuneable, w_meth=write_RegulationTuneable) while True: try: self.impl.set_change_event('RegulationTuneable', True) break except ValueError: self.impl.warn('add_RegulationTuneable', exc_info=1) sleep(0.1) except Tg.DevFailed, df: if df[-1].reason == 'API_AttrNotFound': self.impl.warn('add_RegulationTuneable', exc_info=1) sleep(0.1) else: raise
def __configureRamping(self, attrName, definition, readmethod, writemethod): if self.__device is not None: db = PyTango.Database() step = PyTango.Attr(attrName + "Step", definition['type'], PyTango.READ_WRITE) step.set_memorized() step.set_memorized_init(True) self.__device.add_attribute(step, r_meth=readmethod, w_meth=writemethod) try: devName = self.__device.get_name() stepAttrName = attrName + "Step" attrProp = db.get_device_attribute_property( devName, stepAttrName) propertyValueStr = attrProp[stepAttrName]['__value'][0] value = float(propertyValueStr) rampObj = self._parent.attributes[attrName].getRampObj() rampObj.rampStep = value except: rampObj = self._parent.attributes[attrName].getRampObj() rampObj.rampStep = None stepspeed = PyTango.Attr(attrName + "StepSpeed", PyTango.CmdArgType.DevDouble, PyTango.READ_WRITE) stepspeed.set_memorized() stepspeed.set_memorized_init(True) self.__device.add_attribute(stepspeed, r_meth=readmethod, w_meth=writemethod) try: devName = self.__device.get_name() stepSpeedAttrName = attrName + "StepSpeed" attrProp = db.get_device_attribute_property( devName, stepSpeedAttrName) propertyValueStr = attrProp[attrName + "StepSpeed"]['__value'][0] value = float(propertyValueStr) rampObj = self._parent.attributes[attrName].getRampObj() rampObj.rampStepSpeed = value except: rampObj = self._parent.attributes[attrName].getRampObj() rampObj.rampStepSpeed = None self._attributeList.append(attrName + "Step") self._attributeList.append(attrName + "StepSpeed")
def createReconnectTriggerAttribute(self): attr = PyTango.Attr("Reconnect_Trigger", PyTango.DevDouble, PyTango.AttrWriteType.WRITE) prop = PyTango.UserDefaultAttrProp() prop.set_description( "Triggers a reconnection attempt to the hardware.") attr.set_default_properties(prop) self.add_attribute(attr, self.read_Reconnect_Trigger, self.write_Reconnect_Trigger)
def dyn_attr(self): for process in self.ProcessList: #self.debug_stream('dyn_attr(): Adding attributes for %s process'%process) aname = re.sub('[^0-9a-zA-Z]+', '_', process) for suffix,data_type,data_format,unit in\ (('nprocesses',PyTango.DevLong,PyTango.SCALAR,None), ('nthreads',PyTango.DevLong,PyTango.SCALAR,None), ('pids',PyTango.DevLong,PyTango.SPECTRUM,None), ('cpu',PyTango.DevDouble,PyTango.SCALAR,'%'), ('mem',PyTango.DevDouble,PyTango.SCALAR,'MB'), ('vmem',PyTango.DevDouble,PyTango.SCALAR,'MB'), ('memRatio',PyTango.DevDouble,PyTango.SCALAR,'%'), ('kbpm',PyTango.DevDouble,PyTango.SCALAR,'%'), ): #TODO: set the units if data_format == PyTango.SCALAR: self.add_attribute( PyTango.Attr(aname + '_' + suffix, data_type, PyTango.AttrWriteType.READ), self.read_dyn_attr, None, (lambda s, req_type, attr_name=aname + '_' + suffix: True)) if self.UseEvents: self.set_change_event(aname + '_' + suffix, True, False) elif data_format == PyTango.SPECTRUM: self.add_attribute( PyTango.SpectrumAttr(aname + '_' + suffix, data_type, PyTango.READ, 1000), self.read_dyn_attr, None, (lambda s, req_type, attr_name=aname + '_' + suffix: True)) if self.UseEvents: self.set_change_event(aname + '_' + suffix, True, False) #self._dyn_attr_build = True self.change_state(PyTango.DevState.ON) return
def add_attr(self, aname, rp, slave_index, **extra): impl = self.impl extra['format'] = '%7.4f' index = rp.index + slave_index @PS.AttrExc def read_f(inst, attr): inst.obj_vdq(rp.cobj, index).set_attr(attr) @PS.AttrExc def write_f(inst, wattr): if not self.writeable: raise PS.PS_Exception('tuning regulation parameters disabled') write_value = wattr.get_write_value() inst.obj_set(rp.cobj, index, repr(write_value)) attr = Tg.Attr(aname, Tg.DevDouble, rp.rw) aprop = Tg.UserDefaultAttrProp() if 'desc' in extra: extra['description'] = extra['desc'] del extra['desc'] attr.set_disp_level(Tg.DispLevel.EXPERT) for key, val in extra.iteritems(): getattr(aprop, 'set_' + key)(val) # retries for 10 seconds... for x in range(0, 40): try: self.impl.add_attribute(attr, r_meth=read_f, w_meth=write_f) break except Exception, exc: self.impl.log.debug(str(exc), exc_info=1) sleep(0.25)
def initialize_dynamic_attributes(self): self.debug_stream('In initialize_dynamic_attributes()') if self.pv is not None: # already initialized return # variables initialization READ_METHOD = self.read_attr WRITE_METHOD = self.write_attr if self.Host == []: self.Host = '' self.pv = {} pvs = {} try: # initialize libca library epics.ca.initialize_libca() # get pv names and build libca channels for pv_entry in self.ProcessVariables: pv_attr = pv_entry.split('\t') attr_name = None if len(pv_attr) == 1: pv_name = pv_attr[0] elif len(pv_attr) == 2: pv_name, attr_name = pv_attr else: msg = 'Invalid entry in ProcessVariables device property:'\ ' %s' % pv_entry self.error_stream(msg) self._set_state(PyTango.DevState.FAULT, msg) return # get host name if necessary if self.Host != '': pv_full_name = '%s:%s' % (self.Host, pv_name) else: pv_full_name = pv_name # create epics channel to PV (to increase performance do not # wait for a connection) ch_id = epics.ca.create_channel( pv_full_name, connect=False, auto_cb=False) # build default attribute name (if not provided) if attr_name is None: attr_name = self.epics2tango_name(pv_name) self.pv[attr_name] = [ch_id, pv_full_name] pvs[attr_name] = [ch_id] # connect PVs and get necessary info for name, data in pvs.items(): connected = epics.ca.connect_channel(data[0]) if not connected: msg = 'At least one channel unreachable. Is hardware up?' self.error_stream(msg) self._set_state(PyTango.DevState.FAULT, msg, force_init=True) return epics.ca.poll() # wait for connections completion for name, data in pvs.items(): data.append(epics.ca.field_type(data[0])) data.append(epics.ca.read_access(data[0])) data.append(epics.ca.write_access(data[0])) data.append(epics.ca.element_count(data[0])) # add dynamic attributes for attr_name, data in pvs.items(): # find out tango type tango_type = self.epics2tango_type(data[1]) if tango_type is None: msg = 'Unknown type %s for PV %s' %\ (str(data[1]), self.pv[attr_name][1]) self.error_stream(msg) self._set_state(PyTango.DevState.ALARM, msg) del self.pv[attr_name] continue # find out read/write access read_access = bool(data[2]) write_access = bool(data[3]) read_method = None write_method = None if read_access and write_access: read_method = READ_METHOD write_method = WRITE_METHOD access_type = PyTango.AttrWriteType.READ_WRITE elif read_access and not write_access: read_method = READ_METHOD access_type = PyTango.AttrWriteType.READ elif not read_access and write_access: write_method = WRITE_METHOD access_type = PyTango.AttrWriteType.WRITE else: msg = 'PV %s has neither read nor write permissions'\ % pv_full_name self.error_stream(msg) self._set_state(PyTango.DevState.FAULT, msg) continue # find out dimension and build attribute dimension = data[4] if dimension > 1: attr = PyTango.SpectrumAttr( attr_name, tango_type, access_type, dimension) else: attr = PyTango.Attr( attr_name, tango_type, access_type) properties = PyTango.UserDefaultAttrProp() # set description field with PV name properties.set_description(self.pv[attr_name][1]) attr.set_default_properties(properties) # add attribute self.add_attribute(attr, read_method, write_method) except Exception as e: msg = 'Unable to create dynamic attributes' self.error_stream('%s: %s' % (msg, str(e))) self._set_state(PyTango.DevState.FAULT, msg) del pvs # no longer used
def __getAttrObj(self, attrName, definition, channel=None, function=None, multiple=None): # TODO: image dimensions if self.__device is not None: if definition['dim'] == [0]: if 'writeCmd' in definition: attr = PyTango.Attr(attrName, definition['type'], PyTango.READ_WRITE) readmethod = AttrExc(getattr(self.__device, 'read_attr')) writemethod = AttrExc(getattr(self.__device, 'write_attr')) else: attr = PyTango.Attr(attrName, definition['type'], PyTango.READ) readmethod = AttrExc(getattr(self.__device, 'read_attr')) writemethod = None elif definition['dim'][0] == 1: if 'writeCmd' in definition: attr = PyTango.SpectrumAttr(attrName, definition['type'], PyTango.READ_WRITE, definition['dim'][1]) readmethod = AttrExc(getattr(self.__device, 'read_attr')) writemethod = AttrExc(getattr(self.__device, 'write_attr')) else: attr = PyTango.SpectrumAttr(attrName, definition['type'], PyTango.READ, definition['dim'][1]) readmethod = AttrExc(getattr(self.__device, 'read_attr')) writemethod = None else: raise AttributeError("Not supported multiple dimensions") # attribute properties aprop = PyTango.UserDefaultAttrProp() if 'unit' in definition: aprop.set_unit(latin1(definition['unit'])) if 'min' in definition: aprop.set_min_value(str(definition['min'])) if 'max' in definition: aprop.set_max_value(str(definition['max'])) if 'format' in definition: format = latin1(definition['format']) if format.count("%") == 2: format = format.replace('%', '', 1) aprop.set_format(format) if 'description' in definition: aprop.set_description(latin1(definition['description'])) if 'label' in definition: aprop.set_label(latin1(definition['label'])) if 'memorized' in definition: attr.set_memorized() attr.set_memorized_init(True) attr.set_default_properties(aprop) self.__device.add_attribute(attr, r_meth=readmethod, w_meth=writemethod) multiattr = self.__device.get_device_attr() attrId = multiattr.get_attr_ind_by_name(attrName) self._attributeIds[attrId] = attrName else: attrId = self._generateAttrId(attrName) attr = None aprop = None # self.debug_stream("Attribute %s has the id %s" % (attrName, attrId)) self._attributeList.append(attrName) # prepare internal structure --- if channel is not None or function is not None or multiple is not None: if channel is not None: like = "channel" number = channel elif function is not None: like = "function" number = function elif multiple is not None and \ 'scpiPrefix' in definition['multiple'] and\ 'attrSuffix' in definition['multiple']: like = definition['multiple']['scpiPrefix'] number = multiple else: raise AttributeError("Wrong definition of multiple attribute") self.__prepareChannelLikeAttr(like, number, definition, attrName) else: readCmd = definition['readCmd'] if 'writeCmd' not in definition: # writeCmd = definition['writeCmd'] definition['writeCmd'] = None if 'readFormula' not in definition: # readFormula = definition['readFormula'] definition['readFormula'] = None # if 'writeFormula' not in definition: # # writeFormula = definition['writeFormula'] # writeFormula = None # build internal structure --- if 'rampeable' in definition and definition['rampeable'] is True: self.__buildRWObj(attrName, attrId, definition, readmethod, writemethod) if 'delayAfterWrite' not in definition: definition['delayAfterWrite'] = 0.0 if definition['writeCmd'] is None: self.__buildROObj(attrName, attrId, definition) else: self.__buildRWObj(attrName, attrId, definition) if 'writeValues' in definition: self.__prepareWriteValues(attrName, definition, aprop, attr) return attr
def reader_hook(self, attribute, values): """This method will be executed by the ReaderProcess to process the queried data.""" try: print('>' * 80) print(time.ctime() + ' In reader_hook(%s,[%d])' % (attribute, len(values))) self.counter -= 1 print(self.counter) MAXDIM = 1024 * 1024 * 1024 #First create the attributes epoch, data, aname = [], [], attribute.replace('/', '__') values = decimate_values(values) [(epoch.append(v[0]), data.append(v[1])) for v in values] writable = PyTango.AttrWriteType.READ #Adding time attribute m, atformat, dims = None, PyTango.SpectrumAttr, [MAXDIM] for d in data: if d is not None: if fn.isSequence(d): atformat, dims = PyTango.ImageAttr, [MAXDIM, MAXDIM] m = d[0] else: m = d break attype = PyTango.DevDouble if ( fn.isNumber(m) or fn.isBool(m)) else PyTango.DevString self.add_attribute( PyTango.ImageAttr(aname, attype, writable, MAXDIM, MAXDIM), self.read_dyn_attr, None, self.is_dyn_attr_allowed) self.add_attribute( PyTango.SpectrumAttr(aname + '_t', PyTango.DevDouble, writable, MAXDIM), self.read_dyn_attr, None, self.is_dyn_attr_allowed) self.add_attribute( PyTango.SpectrumAttr(aname + '_d', PyTango.DevString, writable, MAXDIM), self.read_dyn_attr, None, self.is_dyn_attr_allowed) self.add_attribute(atformat(aname + '_r', attype, writable, *dims), self.read_dyn_attr, None, self.is_dyn_attr_allowed) self.add_attribute( PyTango.Attr(aname + '_l', attype, PyTango.AttrWriteType.READ), self.read_dyn_attr, None, self.is_dyn_attr_allowed) self.add_attribute( PyTango.Attr(aname + '_ld', PyTango.DevString, PyTango.AttrWriteType.READ), self.read_dyn_attr, None, self.is_dyn_attr_allowed) #Then add the data to Cache values, so IsDataReady will return True t = fn.now() self.RemoveCachedAttribute(attribute) self.AttrData[attribute] = (t, atformat, attype, values) print('Done: %s,%s,%s,%s,%d' % (attribute, t, atformat, attype, len(values))) except: print(traceback.format_exc())
def CreateAttribute(self, name): # Add your own code here attr = PyTango.Attr(name, PyTango.DevString, PyTango.READ_WRITE) self.add_attribute(attr, self.read_General, self.write_General)
def __getAttrObj(self, attrName, definition, channel=None, function=None, multiple=None): # TODO: image dimensions if definition['dim'] == [0]: if 'writeCmd' in definition: attr = PyTango.Attr(attrName, definition['type'], PyTango.READ_WRITE) readmethod = AttrExc(getattr(self.__device, 'read_attr')) writemethod = AttrExc(getattr(self.__device, 'write_attr')) else: attr = PyTango.Attr(attrName, definition['type'], PyTango.READ) readmethod = AttrExc(getattr(self.__device, 'read_attr')) writemethod = None elif definition['dim'][0] == 1: if 'writeCmd' in definition: attr = PyTango.SpectrumAttr(attrName, definition['type'], PyTango.READ_WRITE, definition['dim'][1]) readmethod = AttrExc(getattr(self.__device, 'read_attr')) writemethod = AttrExc(getattr(self.__device, 'write_attr')) else: attr = PyTango.SpectrumAttr(attrName, definition['type'], PyTango.READ, definition['dim'][1]) readmethod = AttrExc(getattr(self.__device, 'read_attr')) writemethod = None else: raise AttributeError("Not supported multiple dimensions") # attribute properties aprop = PyTango.UserDefaultAttrProp() if 'unit' in definition: aprop.set_unit(latin1(definition['unit'])) if 'min' in definition: aprop.set_min_value(str(definition['min'])) if 'max' in definition: aprop.set_max_value(str(definition['max'])) if 'format' in definition: aprop.set_format(latin1(definition['format'])) if 'description' in definition: aprop.set_description(latin1(definition['description'])) if 'label' in definition: aprop.set_label(latin1(definition['label'])) if 'memorized' in definition: attr.set_memorized() attr.set_memorized_init(True) attr.set_default_properties(aprop) self.__device.add_attribute(attr, r_meth=readmethod, w_meth=writemethod) self._attributeList.append(attrName) # prepare internal structure --- if channel or function or multiple: if channel: like = "channel" elif function: like = "function" elif multiple and 'scpiPrefix' in definition['multiple'] and\ 'attrSuffix' in definition['multiple']: like = definition['multiple']['scpiPrefix'] else: raise AttributeError("Wrong definition of multiple attribute") number = channel or function or multiple self.__prepareChannelLikeAttr(like, number, definition) else: readCmd = definition['readCmd'] if 'writeCmd' not in definition: # writeCmd = definition['writeCmd'] definition['writeCmd'] = None if 'readFormula' not in definition: # readFormula = definition['readFormula'] definition['readFormula'] = None # if 'writeFormula' not in definition: # # writeFormula = definition['writeFormula'] # writeFormula = None # build internal structure --- if definition['writeCmd'] is None: self.__buildROObj(attrName, definition) else: self.__buildRWObj(attrName, definition, readmethod, writemethod) if 'writeValues' in definition: self.__prepareWriteValues(attrName, definition, aprop, attr) return attr
def initialize_dynamic_attributes(self): """ Initialize dynamic attributes """ if self.IsCameraOnline(): # Get attributes multi_attr = self.get_device_attr() # Set minimum and maximum integration time attribute = multi_attr.get_attr_by_name("ExposureTime") multi_prop = attribute.get_properties() multi_prop.unit = self.camera.ExposureTimeAbs.Unit multi_prop.min_value = "{0:.1f}".format( self.camera.ExposureTimeAbs.GetMin()) multi_prop.max_value = "{0:.1f}".format( self.camera.ExposureTimeAbs.GetMax()) attribute.set_properties(multi_prop) attribute.set_change_event(True, False) # Set minimum and maximum gain attribute = multi_attr.get_attr_by_name("Gain") multi_prop = attribute.get_properties() if "Gain" in dir(self.camera): multi_prop.min_value = "{0:.1f}".format( self.camera.Gain.GetMin()) multi_prop.max_value = "{0:.1f}".format( self.camera.Gain.GetMax()) else: multi_prop.min_value = "{0:.1f}".format( self.gc.raw2db(self.camera.GainRaw.GetMin(), self.camera.DeviceModelName())) multi_prop.max_value = "{0:.1f}".format( self.gc.raw2db(self.camera.GainRaw.GetMax(), self.camera.DeviceModelName())) attribute.set_properties(multi_prop) attribute.set_change_event(True, False) # Enable change event on enable trigger attribute = multi_attr.get_attr_by_name("EnableTrigger") attribute.set_change_event(True, False) # Create TriggerSource attribute attr = PT.Attr("TriggerSource", PT.DevEnum, PT.AttrWriteType.READ_WRITE) attr_prop = PT.UserDefaultAttrProp() attr_prop.label = "Trigger Source" attr_prop.set_enum_labels( list(self.camera.TriggerSource.GetSymbolics())) attr.set_default_properties(attr_prop) attr.set_memorized() attr.set_memorized_init(True) attr.set_change_event(True, False) self.add_attribute(attr, self.read_TriggerSource, self.write_TriggerSource, self.IsCameraOnline) # Create PixelFormat attribute attr = PT.Attr("PixelFormat", PT.DevEnum, PT.AttrWriteType.READ_WRITE) attr_prop = PT.UserDefaultAttrProp() attr_prop.label = "Pixel Format" attr_prop.set_enum_labels( list(self.camera.PixelFormat.GetSymbolics())) attr.set_default_properties(attr_prop) attr.set_memorized() attr.set_memorized_init(True) attr.set_change_event(True, False) self.add_attribute(attr, self.read_PixelFormat, self.write_PixelFormat, self.IsCameraOnline) # Create auto-exposure attribute if "ExposureAuto" in dir(self.camera): attr = PT.Attr("AutoExposure", PT.DevEnum, PT.AttrWriteType.READ_WRITE) attr_prop = PT.UserDefaultAttrProp() attr_prop.label = "Auto exposure" attr_prop.set_enum_labels( list(self.camera.ExposureAuto.GetSymbolics())) attr.set_default_properties(attr_prop) attr.set_change_event(True, False) self.add_attribute(attr, self.read_AutoExposure, self.write_AutoExposure, self.IsCameraOnline) # Brightness target attr = PT.Attr("AutoBrightnessTarget", PT.DevUShort, PT.AttrWriteType.READ_WRITE) attr_prop = PT.UserDefaultAttrProp() attr_prop.label = "Auto brightness target" attr_prop.min_value = "{0:d}".format( self.camera.AutoTargetValue.GetMin()) attr_prop.max_value = "{0:d}".format( self.camera.AutoTargetValue.GetMax()) attr_prop.format = "%d" attr.set_default_properties(attr_prop) attr.set_memorized() attr.set_memorized_init(True) attr.set_change_event(True, False) self.add_attribute(attr, self.read_AutoBrightnessTarget, self.write_AutoBrightnessTarget, self.IsCameraOnline) # Exposure time lower limit attr = PT.Attr("AutoExposureLowerLimit", PT.DevDouble, PT.AttrWriteType.READ_WRITE) attr_prop = PT.UserDefaultAttrProp() attr_prop.label = "Auto exposure time lower limit" attr_prop.min_value = "{0:.1f}".format( self.camera.AutoExposureTimeAbsLowerLimit.GetMin()) attr_prop.max_value = "{0:.1f}".format( self.camera.AutoExposureTimeAbsLowerLimit.GetMax()) attr_prop.format = "%.1f" attr_prop.unit = "us" attr.set_default_properties(attr_prop) attr.set_memorized() attr.set_memorized_init(True) attr.set_change_event(True, False) self.add_attribute(attr, self.read_AutoExposureLowerLimit, self.write_AutoExposureLowerLimit, self.IsCameraOnline) # Exposure time upper limit attr = PT.Attr("AutoExposureUpperLimit", PT.DevDouble, PT.AttrWriteType.READ_WRITE) attr_prop = PT.UserDefaultAttrProp() attr_prop.label = "Auto exposure time lower limit" attr_prop.min_value = "{0:.1f}".format( self.camera.AutoExposureTimeAbsUpperLimit.GetMin()) attr_prop.max_value = "{0:.1f}".format( self.camera.AutoExposureTimeAbsUpperLimit.GetMax()) attr_prop.format = "%.1f" attr_prop.unit = "us" attr.set_default_properties(attr_prop) attr.set_memorized() attr.set_memorized_init(True) attr.set_change_event(True, False) self.add_attribute(attr, self.read_AutoExposureUpperLimit, self.write_AutoExposureUpperLimit, self.IsCameraOnline) # Create image attributes # NOTE: also the full image is created as a dynamic attribute because creating it as a static attribute hang the # image callback on push_change_event call attr = PT.ImageAttr("Image", PT.DevUShort, PT.AttrWriteType.READ, 2048, 2048) attr.set_change_event(True, False) self.add_attribute(attr, self.read_image) # Create one image for each defined ROIs for r in self.rois: m = re.match("(\d+):(\d+):(\d+):(\d+)", r) if m is not None: try: x = int(m.groups()[0]) y = int(m.groups()[1]) w = int(m.groups()[2]) h = int(m.groups()[3]) attr_name = "Image_{0:02d}".format(len(self.rois_img)) self.debug_stream( "Adding attribute for roi [X: {0:d}, Y: {1:d}, W: {2:d}, H: {3:d}], named '{4}'" .format(x, y, w, h, attr_name)) attr = PT.ImageAttr(attr_name, PT.DevUShort, PT.AttrWriteType.READ, 2048, 2048) attr.set_change_event(True, False) self.add_attribute(attr, self.read_roi_image) self.rois_img.append({ 'x': x, 'y': y, 'w': w, 'h': h, 'name': attr_name, 'image': None }) except PT.DevFailed as e: self.error_stream( "Failed to create attribute. Error: {0!s}".format( e.args[0])) except Exception as e: self.error_stream( "Failed to create attribute. Error: {0!s}".format( e)) # Initialization done, we can start grabbing self.start_grabbing()