def init_device(self): Device.init_device(self) try: self.pilc = DeviceProxy(self.PiLCFQDN) self.info_stream('Connected to PiLC: {:s}'.format(self.PiLCFQDN)) except: self.error_stream('Could not connect to PiLC: {:s}'.format( self.PiLCFQDN)) return self.set_state(DevState.OFF) self.set_state(DevState.ON) self.db = Database() try: attr = self.db.get_device_attribute_property( self.get_name(), ["exposure"]) self._exposure = int(attr["exposure"]["__value"][0]) except Exception: self._exposure = -1 try: attr = self.db.get_device_attribute_property( self.get_name(), ["mode"]) self._mode = int(attr["mode"]["__value"][0]) except Exception: self._mode = 0
def register(instance_name, *device_names): """Register device with a SDPSubarray device server instance. If the device is already registered, do nothing. :param instance_name: Instance name SDPSubarray device server :param device_names: Subarray device names to register """ # pylint: disable=protected-access try: tango_db = Database() class_name = 'SDPSubarray' server_name = '{}/{}'.format(class_name, instance_name) devices = list(tango_db.get_device_name(server_name, class_name)) device_info = DbDevInfo() device_info._class = class_name device_info.server = server_name for device_name in device_names: device_info.name = device_name if device_name in devices: LOG.debug("Device '%s' already registered", device_name) continue LOG.info('Registering device: %s (server: %s, class: %s)', device_info.name, server_name, class_name) tango_db.add_device(device_info) except ConnectionFailed: pass
def main(): db = Database() """Add device server motor""" new_device_name = "x/foo/motor" new_device_info_motor = DbDevInfo() new_device_info_motor._class = "DS_Motor" new_device_info_motor.server = "DS_Motor/aalonso" print("Creating device: %s" % new_device_name) new_device_info_motor.name = new_device_name db.add_device(new_device_info_motor)
def register_master(): """Register the SDP Master device.""" tango_db = Database() device = "sip_sdp/elt/master" device_info = DbDevInfo() device_info._class = "SDPMasterDevice" device_info.server = "sdp_master_ds/1" device_info.name = device devices = tango_db.get_device_name(device_info.server, device_info._class) if device not in devices: LOG.info('Registering device "%s" with device server "%s"', device_info.name, device_info.server) tango_db.add_device(device_info)
def delete_pb_devices(): """Delete PBs devices from the Tango database.""" parser = argparse.ArgumentParser(description='Register PB devices.') parser.add_argument('num_pb', type=int, help='Number of PBs devices to register.') args = parser.parse_args() log = logging.getLogger('sip.tango_control.subarray') tango_db = Database() log.info("Deleting PB devices:") for index in range(args.num_pb): name = 'sip_sdp/pb/{:05d}'.format(index) log.info("\t%s", name) tango_db.delete_device(name)
def delete_pb_devices(): """Delete PBs devices from the Tango database.""" parser = argparse.ArgumentParser(description='Register PB devices.') parser.add_argument('num_pb', type=int, help='Number of PBs devices to register.') args = parser.parse_args() log = logging.getLogger('sip.tango_control.subarray') tango_db = Database() log.info("Deleting PB devices:") for index in range(args.num_pb): name = 'siid_sdp/pb/{:04d}'.format(index) log.info("\t%s", name) tango_db.delete_device(name)
def register_subarray_devices(): """Register subarray devices.""" tango_db = Database() LOG.info("Registering Subarray devices:") device_info = DbDevInfo() # pylint: disable=protected-access device_info._class = "SubarrayDevice" device_info.server = "subarray_ds/1" for index in range(16): device_info.name = "sip_sdp/elt/subarray_{:02d}".format(index) LOG.info("\t%s", device_info.name) tango_db.add_device(device_info) tango_db.put_class_property(device_info._class, dict(version='1.0.0'))
def configure(self, value): """Schedule an offline only SBI with SDP.""" # Only accept new SBIs if the SDP is on. if self._sdp_state.current_state != 'on': raise RuntimeWarning('Unable to configure SBIs unless SDP is ' '\'on\'.') # Check that the new SBI is not already registered. sbi_config_dict = json.loads(value) sbi_list = SchedulingBlockInstanceList() LOG.info('SBIs before: %s', sbi_list.active) if sbi_config_dict.get('id') in sbi_list.active: raise RuntimeWarning( 'Unable to add SBI with ID {}, an SBI with ' 'this ID is already registered with SDP!'.format( sbi_config_dict.get('id'))) # Add the SBI to the dictionary. LOG.info('Scheduling offline SBI! Config:\n%s', value) sbi = SchedulingBlockInstance.from_config(sbi_config_dict) LOG.info('SBIs after: %s', sbi_list.active) sbi_pb_ids = sbi.processing_block_ids LOG.info('SBI "%s" contains PBs: %s', sbi.id, sbi_pb_ids) # pb_list = ProcessingBlockList() # LOG.info('Active PBs: %s', pb_list.active) # Get the list and number of Tango PB devices tango_db = Database() pb_device_class = "ProcessingBlockDevice" pb_device_server_instance = "processing_block_ds/1" pb_devices = tango_db.get_device_name(pb_device_server_instance, pb_device_class) LOG.info('Number of PB devices in the pool = %d', len(pb_devices)) # Get a PB device which has not been assigned. for pb_id in sbi_pb_ids: for pb_device_name in pb_devices: device = DeviceProxy(pb_device_name) if not device.pb_id: LOG.info('Assigning PB device = %s to PB id = %s', pb_device_name, pb_id) # Set the device attribute 'pb_id' to the processing block # id it is tracking. device.pb_id = pb_id break
def delete_device_server(instance_name: str = "*"): """Delete (unregister) SDPMaster device server instance(s). :param instance_name: Optional, name of the device server instance to remove. If not specified all service instances will be removed. """ try: tango_db = Database() class_name = 'SDPMaster' server_name = '{}/{}'.format(class_name, instance_name) for server_name in list(tango_db.get_server_list(server_name)): LOG.info('Removing device server: %s', server_name) tango_db.delete_server(server_name) except ConnectionFailed: pass
def setUpClass(cls): cls.db = Database() cls.add_devices() sleep(2) for device_server in cls.REQUIRED_DEVICE_SERVERS: cls.start_device_server(device_server) sleep(2)
def test_ska_devices(): """Check SKA devices against the Tango developers guide.""" devices = Database().get_device_exported("*") devices = list(filter(check_mid_low, devices)) request_headers = get_job_token_header() if request_headers: logging.info("Using job token") test_result = {} with NamedTemporaryFile(mode="wb") as tmp_file: spec_response = requests.get(SPEC_URLS["ska_tango_guide_ska_wide"], headers=request_headers) spec_response.raise_for_status() tmp_file.write(spec_response.content) tmp_file.seek(0) for device in devices: result = validate_device_from_path(device, tmp_file.name, False) if result: test_result.setdefault(result, []).append(device) logging.info( "Checked %s devices against spec, %s\n", len(devices), SPEC_URLS["ska_tango_guide_ska_wide"], ) for result, devices in test_result.items(): logging.info(">>> Devices %s\nHave the following issues:\n%s\n", devices, result) assert not test_result.keys()
def configure(self, value): """Schedule an offline only SBI with SDP.""" # Only accept new SBIs if the SDP is on. if self._sdp_state.current_state != 'on': raise RuntimeWarning('Unable to configure SBIs unless SDP is ' '\'on\'.') # Check that the new SBI is not already registered. sbi_config_dict = json.loads(value) sbi_list = SchedulingBlockInstanceList() LOG.info('SBIs before: %s', sbi_list.active) if sbi_config_dict.get('id') in sbi_list.active: raise RuntimeWarning('Unable to add SBI with ID {}, an SBI with ' 'this ID is already registered with SDP!' .format(sbi_config_dict.get('id'))) # Add the SBI to the dictionary. LOG.info('Scheduling offline SBI! Config:\n%s', value) sbi = SchedulingBlockInstance.from_config(sbi_config_dict) LOG.info('SBIs after: %s', sbi_list.active) sbi_pb_ids = sbi.processing_block_ids LOG.info('SBI "%s" contains PBs: %s', sbi.id, sbi_pb_ids) # pb_list = ProcessingBlockList() # LOG.info('Active PBs: %s', pb_list.active) # Get the list and number of Tango PB devices tango_db = Database() pb_device_class = "ProcessingBlockDevice" pb_device_server_instance = "processing_block_ds/1" pb_devices = tango_db.get_device_name(pb_device_server_instance, pb_device_class) LOG.info('Number of PB devices in the pool = %d', len(pb_devices)) # Get a PB device which has not been assigned. for pb_id in sbi_pb_ids: for pb_device_name in pb_devices: device = DeviceProxy(pb_device_name) if not device.pb_id: LOG.info('Assigning PB device = %s to PB id = %s', pb_device_name, pb_id) # Set the device attribute 'pb_id' to the processing block # id it is tracking. device.pb_id = pb_id break
def processing_block_devices(self): """Get list of processing block devices.""" # Get the list and number of Tango PB devices tango_db = Database() pb_device_class = "ProcessingBlockDevice" pb_device_server_instance = "processing_block_ds/1" pb_devices = tango_db.get_device_name(pb_device_server_instance, pb_device_class) LOG.info('Number of PB devices in the pool = %d', len(pb_devices)) pb_device_map = [] for pb_device_name in pb_devices: device = DeviceProxy(pb_device_name) if device.pb_id: LOG.info('%s %s', pb_device_name, device.pb_id) pb_device_map.append((pb_device_name, device.pb_id)) return str(pb_device_map)
def init_device(self): super().init_device() self.info_stream("init_device()") if self.Axis == 0: self.__Axis_Name = "X" else: self.__Axis_Name = "Y" self.info_stream("module address: {:d}".format(self.Address)) self.info_stream("module axis: {:d}".format(self.Axis)) self.info_stream("alias: {:s}".format(self.Alias)) try: self.ctrl = DeviceProxy(self.CtrlDevice) self.info_stream("ctrl. device: {:s}".format(self.CtrlDevice)) except DevFailed as df: self.error_stream("failed to create proxy to {:s}".format(df)) sys.exit(255) # check if the CrlDevice ON, if not open the serial port if str(self.ctrl.state()) == "OFF": self.ctrl.open() self.info_stream("controller sucessfully opened") else: self.info_stream("controller was already open") if ("MCC" in self.read_firmware_version()): # read memorized attributes from Database self.db = Database() try: attr = self.db.get_device_attribute_property(self.get_name(), ["inverted"]) if attr["inverted"]["__value"][0] == "true": self.__Inverted = True else: self.__Inverted = False except Exception: self.__Inverted = False self.set_state(DevState.ON) else: self.set_state(DevState.OFF) self.info_stream("HW limit-: {0}".format(self.__HW_Limit_Minus)) self.info_stream("HW limit+: {0}".format(self.__HW_Limit_Plus))
def register_pb_devices(num_pbs: int = 100): """Register PBs devices. Note(BMo): Ideally we do not want to register any devices here. There does not seem to be a way to create a device server with no registered devices in Tango. This is (probably) because Tango devices must have been registered before the server starts ... """ tango_db = Database() LOG.info("Registering PB devices:") dev_info = DbDevInfo() # pylint: disable=protected-access dev_info._class = 'ProcessingBlockDevice' dev_info.server = 'processing_block_ds/1' for index in range(num_pbs): dev_info.name = 'sip_sdp/pb/{:05d}'.format(index) LOG.info("\t%s", dev_info.name) tango_db.add_device(dev_info)
def test_init(): logging.info("Init test traces") timeSleep = 30 for x in range(10): try: logging.info("Connecting to the databaseds") db = Database() break except Exception: logging.info("Could not connect to the databaseds. Retry after " + str(timeSleep) + " seconds.") sleep(timeSleep) logging.info("Connected to the databaseds")
def device_enum_labels_map(): """Query the database and retrieve enum labels for devices with obsState attribute in their device""" devices_and_enums = {} db = Database() device_names = db.get_device_exported("*") for dev_name in device_names: dp = DeviceProxy(dev_name) attribute_list = dp.get_attribute_list() # skip all devices without the obsState attribute if "obsState" not in attribute_list: continue enum_labels = dp.get_attribute_config("obsState").enum_labels # cast label from tango._tango.StdStringVector to List enum_labels = list(enum_labels) formatted_enum_labels = _remove_special_characters_from_enum_labels( enum_labels) devices_and_enums[dev_name] = formatted_enum_labels return devices_and_enums
def test_init(): print("Init test devices") timeSleep = 30 for x in range(10): try: print("Connecting to the databaseds") db = Database() break except: print("Could not connect to the databaseds. Retry after " + str(timeSleep) + " seconds.") sleep(timeSleep) print("Connected to the databaseds")
def test_devices(): db = Database() count = 0 server_list = db.get_server_list() i = 0 while i < len(server_list): class_list = db.get_device_class_list(server_list[i]) j = 0 while j < len(class_list): try: if not "dserver" in class_list[j]: print("Connecting to '" + class_list[j] + "'...\r\n") dev = DeviceProxy(class_list[j]) count = count + 1 except Exception as e: print("Could not connect to the '" + class_list[j] + "' DeviceProxy.\r\n") print(e) j += 2 i += 1 print("Total number of active devices " + str(count) + ".") assert count > 50
def __register_server(server_type, server_instance, domain=None, family='bliss', member=None, klass=None, db=None): beamline = os.environ.get('BEAMLINENAME', 'bliss') server_name = '{0}/{1}'.format(server_type, server_instance) domain = domain or beamline member = member or server_instance klass = klass or server_type db = db or Database() dev_name = '{0}/{1}/{2}'.format(domain, family, member) config_dir = '~/local/beamline_control' config_file = os.path.join(config_dir, '{0}.yml'.format(beamline)) # try to find which configuration file to use. # if we are not able we ask the user. print_("'{0}' is not configured yet.".format(server_instance)) if not os.path.exists(os.path.expanduser(config_file)): config_file = '' config_file = raw_input('config. file [{0}]? '.format(config_file)) or \ config_file config_file = os.path.expanduser(config_file) if not config_file: print_('No configuration file was given. Exiting...') sys.exit(-1) if not os.path.exists(os.path.expanduser(config_file)): print_('Could not find configuration file. Exiting...') sys.exit(-2) properties = dict(config_file=config_file) # ask the user for the session name session_name = server_instance session_name = raw_input('session name {0}? '.format(session_name)) or \ session_name if session_name != server_instance: properties['session_name'] = session_name _log.info("registering new server: %s with %s device %s", server_name, klass, dev_name) info = DbDevInfo() info.server = server_name info._class = klass info.name = dev_name db.add_device(info) db.put_device_property(dev_name, dict(config_file=config_file))
def tango_context(request): """Creates and returns a TANGO DeviceTestContext object. :param request: _pytest.fixtures.SubRequest A request object gives access to the requesting test context. """ DishMaster = get_tango_server_class("test/nodb/dishmaster") _, tango_db_path = tempfile.mkstemp(prefix="tango") tango_context = DeviceTestContext( DishMaster, db=tango_db_path, process=False, properties={} ) mock_get_db = mock.Mock(return_value=Database(tango_context.db)) helper_module.get_database = mock_get_db tango_context.start() yield tango_context tango_context.stop()
class CachedDatabase(object): """A TANGO database wrapper that caches 'get' methods.""" _db = Database() _methods = {} def __init__(self, ttl): self._ttl = ttl def __getattr__(self, method): if not method.startswith("get_"): # caching 'set' methods doesn't make any sense anyway # TODO: check that this really catches the right methods return getattr(self._db, method) if method not in self._methods: self._methods[method] = CachedMethod(getattr(self._db, method), ttl=self._ttl) return self._methods[method]
def register_subarray_devices(): """Register subarray devices.""" tango_db = Database() LOG.info("Registering Subarray devices:") device_info = DbDevInfo() # pylint: disable=protected-access device_info._class = "SubarrayDevice" device_info.server = "subarray_ds/1" for index in range(16): device_info.name = "siid_sdp/elt/subarray_{:02d}".format(index) LOG.info("\t%s", device_info.name) tango_db.add_device(device_info) tango_db.put_class_property(device_info._class, dict(version='1.0.0'))
class PhytronMCC2Axis(Device): # device properties CtrlDevice = device_property( dtype="str", default_value="domain/family/member" ) Axis = device_property( dtype="int16" ) Address = device_property( dtype="int16" ) Alias = device_property( dtype="str" ) # device attributes hw_limit_minus = attribute( dtype="bool", label="HW limit -", access=AttrWriteType.READ, display_level=DispLevel.OPERATOR, ) hw_limit_plus = attribute( dtype="bool", label="HW limit +", access=AttrWriteType.READ, display_level=DispLevel.OPERATOR, ) sw_limit_minus = attribute( dtype="float", format="%8.3f", label="SW limit -", unit="steps", access=AttrWriteType.READ_WRITE, display_level=DispLevel.EXPERT, ) sw_limit_plus = attribute( dtype="float", format="%8.3f", label="SW limit +", unit="steps", access=AttrWriteType.READ_WRITE, display_level=DispLevel.EXPERT, ) position = attribute( dtype="float", format="%8.3f", label="position", unit="steps", access=AttrWriteType.READ_WRITE, display_level=DispLevel.OPERATOR, ) alias = attribute( dtype="string", label="alias", access=AttrWriteType.READ, display_level=DispLevel.OPERATOR, ) inverted = attribute( dtype="bool", label="inverted", memorized=True, access=AttrWriteType.READ_WRITE, display_level=DispLevel.EXPERT, ) acceleration = attribute( dtype="int", label="acceleration", unit="Hz", min_value=4000, max_value=500000, access=AttrWriteType.READ_WRITE, display_level=DispLevel.EXPERT, ) velocity = attribute( dtype="int", label="velocity", unit="Hz", min_value=0, max_value=40000, access=AttrWriteType.READ_WRITE, display_level=DispLevel.EXPERT, ) homing_velocity = attribute( dtype="int", label="homing velocity", unit="Hz", min_value=0, max_value=40000, access=AttrWriteType.READ_WRITE, display_level=DispLevel.EXPERT, ) hold_current = attribute( dtype="float", label="hold current", unit="A", min_value=0, max_value=2.5, format="%2.1f", access=AttrWriteType.READ_WRITE, display_level=DispLevel.EXPERT, ) run_current = attribute( dtype="float", label="run current", unit="A", min_value=0, max_value=2.5, format="%2.1f", access=AttrWriteType.READ_WRITE, display_level=DispLevel.EXPERT, ) initiator_type = attribute( dtype=InitiatorType, label="initiator type", access=AttrWriteType.READ_WRITE, display_level=DispLevel.EXPERT, ) steps_per_unit = attribute( dtype="float", format="%10.1f", label="steps per unit", access=AttrWriteType.READ_WRITE, display_level=DispLevel.EXPERT, ) step_resolution = attribute( dtype="int", label="step resolution", access=AttrWriteType.READ_WRITE, display_level=DispLevel.EXPERT, doc="""Step resolution 1 to 256 1 = Full step 2 = Half step 4 = 1/4 step 8 = 1/8 step 10 = 1/10 step 16 = 1/16 step 128 = 1/128 step 256 = 1/256 step""" ) backlash_compensation = attribute( dtype="int", label="backlash compensation", unit="step", access=AttrWriteType.READ_WRITE, display_level=DispLevel.EXPERT, ) type_of_movement = attribute( dtype=MovementType, label="type of movement", access=AttrWriteType.READ_WRITE, display_level=DispLevel.EXPERT, doc="""0 = rotational Rotating table, 1 limit switch for mechanical zero (referencing) 1 = linear for XY tables or other linear systems, 2 limit switches: Mechanical zero and limit direction - Limit direction +""" ) movement_unit = attribute( dtype=MovementUnit, label="unit", access=AttrWriteType.READ_WRITE, display_level=DispLevel.EXPERT, doc="Allowed unit values are step, mm, inch, degree" ) # private class properties __NACK = chr(0x15) # command failed __LIM_PLUS = 2 __LIM_MINUS = 1 __Axis_Name = '' __HW_Limit_Minus = False __HW_Limit_Plus = False __Inverted = False __Unit = MovementUnit.step __Steps_Per_Unit = 1.0 def init_device(self): super().init_device() self.info_stream("init_device()") if self.Axis == 0: self.__Axis_Name = "X" else: self.__Axis_Name = "Y" self.info_stream("module address: {:d}".format(self.Address)) self.info_stream("module axis: {:d}".format(self.Axis)) self.info_stream("alias: {:s}".format(self.Alias)) try: self.ctrl = DeviceProxy(self.CtrlDevice) self.info_stream("ctrl. device: {:s}".format(self.CtrlDevice)) except DevFailed as df: self.error_stream("failed to create proxy to {:s}".format(df)) sys.exit(255) # check if the CrlDevice ON, if not open the serial port if str(self.ctrl.state()) == "OFF": self.ctrl.open() self.info_stream("controller sucessfully opened") else: self.info_stream("controller was already open") if ("MCC" in self.read_firmware_version()): # read memorized attributes from Database self.db = Database() try: attr = self.db.get_device_attribute_property(self.get_name(), ["inverted"]) if attr["inverted"]["__value"][0] == "true": self.__Inverted = True else: self.__Inverted = False except Exception: self.__Inverted = False self.set_state(DevState.ON) else: self.set_state(DevState.OFF) self.info_stream("HW limit-: {0}".format(self.__HW_Limit_Minus)) self.info_stream("HW limit+: {0}".format(self.__HW_Limit_Plus)) def delete_device(self): self.set_state(DevState.OFF) def always_executed_hook(self): answer = self._send_cmd("SE") if (self.Axis == 0): if self.__Inverted: self.__HW_Limit_Minus = bool(int(answer[2]) & self.__LIM_PLUS) self.__HW_Limit_Plus = bool(int(answer[2]) & self.__LIM_MINUS) else: self.__HW_Limit_Minus = bool(int(answer[2]) & self.__LIM_MINUS) self.__HW_Limit_Plus = bool(int(answer[2]) & self.__LIM_PLUS) moving = not(bool(int(answer[1]) & 1)) else: if self.__Inverted: self.__HW_Limit_Minus = bool(int(answer[6]) & self.__LIM_PLUS) self.__HW_Limit_Plus = bool(int(answer[6]) & self.__LIM_MINUS) else: self.__HW_Limit_Minus = bool(int(answer[6]) & self.__LIM_MINUS) self.__HW_Limit_Plus = bool(int(answer[6]) & self.__LIM_PLUS) moving = not(bool(int(answer[5]) & 1)) self.debug_stream("HW limit-: {0}".format(self.__HW_Limit_Minus)) self.debug_stream("HW limit+: {0}".format(self.__HW_Limit_Plus)) if moving is False: self.set_status("Device in ON") self.set_state(DevState.ON) self.debug_stream("device is: ON") else: self.set_status("Device is MOVING") self.set_state(DevState.MOVING) self.debug_stream("device is: MOVING") # attribute read/write methods def read_hw_limit_minus(self): return self.__HW_Limit_Minus def read_hw_limit_plus(self): return self.__HW_Limit_Plus def read_sw_limit_minus(self): ret = float(self.send_cmd("P24R")) if self.__Inverted: return -1*ret else: return ret def write_sw_limit_minus(self, value): if self.__Inverted: value = -1*value self.send_cmd("P24S{:f}".format(value)) def read_sw_limit_plus(self): ret = float(self.send_cmd("P23R")) if self.__Inverted: return -1*ret else: return ret def write_sw_limit_plus(self, value): if self.__Inverted: value = -1*value self.send_cmd("P23S{:f}".format(value)) def read_position(self): ret = float(self.send_cmd("P20R")) if self.__Inverted: return -1*ret else: return ret def write_position(self, value): if self.__Inverted: value = -1*value answer = self.send_cmd("A{:.10f}".format(value)) if answer != self.__NACK: self.set_state(DevState.MOVING) def read_alias(self): return self.Alias def read_inverted(self): return self.__Inverted def write_inverted(self, value): self.__Inverted = bool(value) def read_acceleration(self): return int(self.send_cmd("P15R")) def write_acceleration(self, value): self.send_cmd("P15S{:d}".format(value)) def read_velocity(self): return int(self.send_cmd("P14R")) def write_velocity(self, value): self.send_cmd("P14S{:d}".format(value)) def read_homing_velocity(self): return int(self.send_cmd("P08R")) def write_homing_velocity(self, value): self.send_cmd("P08S{:d}".format(value)) def read_run_current(self): return float(self.send_cmd("P41R"))/10 def write_run_current(self, value): value = int(value*10) if value not in range(0, 26): return "input not in range 0..25" self.send_cmd("P41S{:d}".format(value)) def read_hold_current(self): return float(self.send_cmd("P40R"))/10 def write_hold_current(self, value): value = int(value*10) if value not in range(0, 26): return "input not in range 0..25" self.send_cmd("P40S{:d}".format(value)) def read_initiator_type(self): return InitiatorType.NOC if bool(int(self.send_cmd("P27R"))) else InitiatorType.NCC def write_initiator_type(self, value): self.send_cmd("P27S{:d}".format(int(value))) def read_steps_per_unit(self): # inverse of spindle pitch (see manual page 50) self.__Steps_Per_Unit = 1/float(self.send_cmd("P03R")) return self.__Steps_Per_Unit def write_steps_per_unit(self, value): # inverse of spindle pitch (see manual page 50) self.send_cmd("P03S{:10.8f}".format(1/value)) # update display unit self.set_display_unit() def read_step_resolution(self): return int(self.send_cmd("P45R")) def write_step_resolution(self, value): if value not in [1, 2, 4, 8, 10, 16, 128, 256]: return "input not in [1, 2, 4, 8, 10, 16, 128, 256]" self.send_cmd("P45S{:d}".format(value)) def read_backlash_compensation(self): ret = int(self.send_cmd("P25R")) if self.__Inverted: return -1*ret else: return ret def write_backlash_compensation(self, value): if self.__Inverted: value = -1*value self.send_cmd("P25S{:d}".format(int(value))) def read_type_of_movement(self): return MovementType.linear if bool(int(self.send_cmd("P01R"))) else MovementType.rotational def write_type_of_movement(self, value): self.send_cmd("P01S{:d}".format(int(value))) def read_movement_unit(self): res = int(self.send_cmd("P02R")) if res == 1: self.__Unit = MovementUnit.step elif res == 2: self.__Unit = MovementUnit.mm elif res == 3: self.__Unit = MovementUnit.inch elif res == 4: self.__Unit = MovementUnit.degree return self.__Unit def write_movement_unit(self, value): self.send_cmd("P02S{:d}".format(int(value+1))) self.read_movement_unit() self.set_display_unit() # internal methods def set_display_unit(self): attributes = [b"position", b"sw_limit_minus", b"sw_limit_plus"] for attr in attributes: ac3 = self.get_attribute_config_3(attr) ac3[0].unit = self.__Unit.name.encode("utf-8") if (1/self.__Steps_Per_Unit % 1) == 0.0: ac3[0].format = b"%8d" else: ac3[0].format = b"%8.3f" self.set_attribute_config_3(ac3) def _send_cmd(self, cmd): # add module address to beginning of command cmd = str(self.Address) + cmd res = self.ctrl.write_read(cmd) if res == self.__NACK: self.set_state(DevState.FAULT) self.warn_stream("command not acknowledged from controller " "-> Fault State") return "" return res # commands @command(dtype_in=str, dtype_out=str, doc_in="enter a command", doc_out="the response") def send_cmd(self, cmd): # add axis name (X, Y) to beginning of command return self._send_cmd(str(self.__Axis_Name) + cmd) @command(dtype_out=str, doc_out="the firmware version") def read_firmware_version(self): version = self._send_cmd("IVR") return version @command(dtype_in=float, doc_in="position") def set_position(self, value): if self.__Inverted: value = -1*value self.send_cmd("P20S{:.4f}".format(value)) @command def jog_plus(self): if self.__Inverted: self.send_cmd("L-") else: self.send_cmd("L+") self.set_state(DevState.MOVING) @command def jog_minus(self): if self.__Inverted: self.send_cmd("L+") else: self.send_cmd("L-") self.set_state(DevState.MOVING) @command def homing_plus(self): if self.__Inverted: self.send_cmd("0-") else: self.send_cmd("0+") self.set_state(DevState.MOVING) @command def homing_minus(self): if self.__Inverted: self.send_cmd("0+") else: self.send_cmd("0-") self.set_state(DevState.MOVING) @command def stop(self): self.send_cmd("S") self.set_state(DevState.ON) @command def abort(self): self.send_cmd("SN") self.set_state(DevState.ON) @command(dtype_in=str) def set_alias(self, name): self.Alias = name self.db.put_device_property(self.get_name(), {"Alias": name}) @command(dtype_out=str) def write_to_eeprom(self): self._send_cmd("SA") self.info_stream("parameters written to EEPROM") return "parameters written to EEPROM" @command(dtype_out=str) def dump_config(self): parameters = range(1, 50) res = "" for par in parameters: cmd = "P{:02d}R".format(par) res = res + "P{:02d}: {:s}\n".format(par, str(self.send_cmd(cmd))) return res
def __init__(self): self.db = Database() self.replicas = 1 self.replica_id = 0 pass
class CustomCollector(object): def __init__(self): self.db = Database() self.replicas = 1 self.replica_id = 0 pass def add_to_metric(self, dev, attr_info, metric): if (attr_info.data_type == ArgType.DevShort or attr_info.data_type == ArgType.DevLong or attr_info.data_type == ArgType.DevUShort or attr_info.data_type == ArgType.DevULong or attr_info.data_type == ArgType.DevLong64 or attr_info.data_type == ArgType.DevULong64 or attr_info.data_type == ArgType.DevInt or attr_info.data_type == ArgType.DevFloat or attr_info.data_type == ArgType.DevDouble): attr_value = dev.read_attribute(attr_info.name) metric.add_metric([ dev.dev_name(), attr_info.name, attr_info.label, '', 'float', str(attr_value.dim_x), str(attr_value.dim_y), '0', '0' ], float(attr_value.value)) return 1 elif (attr_info.data_type == ArgType.DevBoolean): attr_value = dev.read_attribute(attr_info.name) metric.add_metric([ dev.dev_name(), attr_info.name, attr_info.label, '', 'bool', str(attr_value.dim_x), str(attr_value.dim_y), '0', '0' ], int(attr_value.value)) return 1 elif (attr_info.data_type == ArgType.DevString): attr_value = dev.read_attribute(attr_info.name) metric.add_metric([ dev.dev_name(), attr_info.name, attr_info.label, str(attr_value.value), 'string', str(attr_value.dim_x), str(attr_value.dim_y), '0', '0' ], 1) return 1 elif (attr_info.data_type == ArgType.DevEnum): attr_config = dev.get_attribute_config(attr_info.name) attr_value = dev.read_attribute(attr_info.name) metric.add_metric([ dev.dev_name(), attr_info.name, attr_info.label, str(attr_config.enum_labels[attr_value.value]), 'enum', str(attr_value.dim_x), str(attr_value.dim_y), '0', '0' ], int(attr_value.value)) return 1 elif (attr_info.data_type == ArgType.DevState): attr_value = dev.read_attribute(attr_info.name) metric.add_metric([ dev.dev_name(), attr_info.name, attr_info.label, str(attr_value.value), 'state', str(attr_value.dim_x), str(attr_value.dim_y), '0', '0' ], int(attr_value.value)) return 1 else: return 0 def add_to_metric_spectrum(self, dev, attr_info, metric): attr_value = dev.read_attribute(attr_info.name) for x in range(int(attr_value.dim_x)): if (attr_info.data_type == ArgType.DevShort or attr_info.data_type == ArgType.DevLong or attr_info.data_type == ArgType.DevUShort or attr_info.data_type == ArgType.DevULong or attr_info.data_type == ArgType.DevLong64 or attr_info.data_type == ArgType.DevULong64 or attr_info.data_type == ArgType.DevInt or attr_info.data_type == ArgType.DevFloat or attr_info.data_type == ArgType.DevDouble): metric.add_metric([ dev.dev_name(), attr_info.name, attr_info.label, '', 'float', str(attr_value.dim_x), str(attr_value.dim_y), str(x), '0' ], float(attr_value.value[x])) elif (attr_info.data_type == ArgType.DevBoolean): metric.add_metric([ dev.dev_name(), attr_info.name, attr_info.label, '', 'bool', str(attr_value.dim_x), str(attr_value.dim_y), str(x), '0' ], int(attr_value.value[x])) elif (attr_info.data_type == ArgType.DevString): metric.add_metric([ dev.dev_name(), attr_info.name, attr_info.label, str(attr_value.value[x]), 'string', str(attr_value.dim_x), str(attr_value.dim_y), str(x), '0' ], 1) elif (attr_info.data_type == ArgType.DevEnum): metric.add_metric([ dev.dev_name(), attr_info.name, attr_info.label, str(attr_value.value[x]), 'enum', str(attr_value.dim_x), str(attr_value.dim_y), str(x), '0' ], int(attr_value.value[x])) elif (attr_info.data_type == ArgType.DevState): metric.add_metric([ dev.dev_name(), attr_info.name, attr_info.label, str(attr_value.value[x]), 'state', str(attr_value.dim_x), str(attr_value.dim_y), str(x), '0' ], int(attr_value.value[x])) else: pass return 1 def add_to_metric_image(self, dev, attr_info, metric): attr_value = dev.read_attribute(attr_info.name) for y in range(int(attr_value.dim_y)): for x in range(int(attr_value.dim_x)): if (attr_info.data_type == ArgType.DevShort or attr_info.data_type == ArgType.DevLong or attr_info.data_type == ArgType.DevUShort or attr_info.data_type == ArgType.DevULong or attr_info.data_type == ArgType.DevLong64 or attr_info.data_type == ArgType.DevULong64 or attr_info.data_type == ArgType.DevInt or attr_info.data_type == ArgType.DevFloat or attr_info.data_type == ArgType.DevDouble): metric.add_metric([ dev.dev_name(), attr_info.name, attr_info.label, '', 'float', str(attr_value.dim_x), str(attr_value.dim_y), str(x), str(y) ], float(attr_value.value[y][x])) elif (attr_info.data_type == ArgType.DevBoolean): metric.add_metric([ dev.dev_name(), attr_info.name, attr_info.label, '', 'bool', str(attr_value.dim_x), str(attr_value.dim_y), str(x), str(y) ], int(attr_value.value[y][x])) elif (attr_info.data_type == ArgType.DevString): metric.add_metric([ dev.dev_name(), attr_info.name, attr_info.label, str(attr_value.value[y][x]), 'string', str(attr_value.dim_x), str(attr_value.dim_y), str(x), str(y) ], 1) elif (attr_info.data_type == ArgType.DevEnum): metric.add_metric([ dev.dev_name(), attr_info.name, attr_info.label, str(attr_value.value[y][x]), 'enum', str(attr_value.dim_x), str(attr_value.dim_y), str(x), str(y) ], int(attr_value.value[y][x])) elif (attr_info.data_type == ArgType.DevState): metric.add_metric([ dev.dev_name(), attr_info.name, attr_info.label, str(attr_value.value[y][x]), 'state', str(attr_value.dim_x), str(attr_value.dim_y), str(x), str(y) ], int(attr_value.value[y][x])) else: pass return 1 def collect(self): attribute_metrics = GaugeMetricFamily("device_attribute", 'Device attribute value', labels=[ 'device', 'name', 'label', 'str_value', 'type', 'dim_x', 'dim_y', 'x', 'y' ]) total_count = 0 read_count = 0 error_count = 0 error_attr_count = 0 scalar_count = 0 spectrum_count = 0 image_count = 0 not_managed_attribute_count = 0 try: server_list = self.db.get_server_list() except: try: self.db = Database() except: return count = len(server_list) / self.replicas # 15,8 i = int(count * self.replica_id) # 0 15,8 31,6 47,4 63,2 -> 0 15 31 47 63 count = int(count) + i # 15 31 47 63 if (self.replicas - 1 == self.replica_id): count = len(server_list) # 79 #print("i=" + str(i) +",count="+str(count)) while i < count: # https://pytango.readthedocs.io/en/stable/database.html#tango.Database.get_device_class_list class_list = self.db.get_device_class_list(server_list[i]) j = 0 while j < len(class_list): try: if "dserver" in class_list[j]: j += 2 continue dev = DeviceProxy(class_list[j]) #print(class_list[j]) dev.set_timeout_millis(10) attr_list = dev.attribute_list_query() for attr_info in attr_list: try: #print(" " +attr_info.name) total_count += 1 # 1: tango._tango.CmdArgType.DevBoolean, # 2: tango._tango.CmdArgType.DevShort, # 3: tango._tango.CmdArgType.DevLong, # 4: tango._tango.CmdArgType.DevFloat, # 5: tango._tango.CmdArgType.DevDouble, # 6: tango._tango.CmdArgType.DevUShort, # 7: tango._tango.CmdArgType.DevULong, # 8: tango._tango.CmdArgType.DevString, # 19: tango._tango.CmdArgType.DevState, # 23: tango._tango.CmdArgType.DevLong64, # 24: tango._tango.CmdArgType.DevULong64, # 27: tango._tango.CmdArgType.DevInt, # 29: tango._tango.CmdArgType.DevEnum, if (attr_info.data_format == AttrDataFormat.SCALAR ): res = self.add_to_metric( dev, attr_info, attribute_metrics) if (res > 0): read_count = read_count + res scalar_count += 1 else: # {0: tango._tango.CmdArgType.DevVoid, # 28: tango._tango.CmdArgType.DevEncoded, # 30: tango._tango.CmdArgType.DevPipeBlob, # 22: tango._tango.CmdArgType.DevUChar, # 20: tango._tango.CmdArgType.ConstDevString, not_managed_attribute_count += 1 #print("*******NOT MANAGED: "+attr_info.name) # 9: tango._tango.CmdArgType.DevVarCharArray, # 10: tango._tango.CmdArgType.DevVarShortArray, # 11: tango._tango.CmdArgType.DevVarLongArray, # 12: tango._tango.CmdArgType.DevVarFloatArray, # 13: tango._tango.CmdArgType.DevVarDoubleArray, # 14: tango._tango.CmdArgType.DevVarUShortArray, # 15: tango._tango.CmdArgType.DevVarULongArray, # 16: tango._tango.CmdArgType.DevVarStringArray, # 17: tango._tango.CmdArgType.DevVarLongStringArray, # 18: tango._tango.CmdArgType.DevVarDoubleStringArray, # 21: tango._tango.CmdArgType.DevVarBooleanArray, # 25: tango._tango.CmdArgType.DevVarLong64Array, # 26: tango._tango.CmdArgType.DevVarULong64Array, # 31: tango._tango.CmdArgType.DevVarStateArray} elif (attr_info.data_format == AttrDataFormat.SPECTRUM): res = self.add_to_metric_spectrum( dev, attr_info, attribute_metrics) if (res <= 0): not_managed_attribute_count += 1 #print("*******NOT MANAGED: "+attr_info.name) else: spectrum_count += 1 read_count += 1 elif (attr_info.data_format == AttrDataFormat.IMAGE ): # res = self.add_to_metric_image(dev, attr_info, attribute_metrics) # if(res <= 0): not_managed_attribute_count += 1 #print("*******NOT MANAGED: "+attr_info.name) image_count += 1 # read_count += 1 else: # AttrDataFormat.FMT_UNKNOWN not_managed_attribute_count += 1 #print("*******NOT MANAGED: "+attr_info.name) except Exception as e1: #print ("Could not connect to the '"+ class_list[j] + "." + attr_info.name+"' Attribute.\r\n") #print(e1) error_attr_count += 1 except Exception as e2: #print ("Could not connect to the '"+class_list[j]+"' DeviceProxy.\r\n") #print(e2) error_count += 1 j += 2 i += 1 yield attribute_metrics errors = GaugeMetricFamily( "error_count", 'Total number of errors reading the devices') errors.add_metric([], error_count) yield errors errors_attr = GaugeMetricFamily( "error_attr_count", 'Total number of errors reading the device attributes') errors_attr.add_metric([], error_attr_count) yield errors_attr attribute_count = GaugeMetricFamily("attribute_count", 'Total number of attributes') attribute_count.add_metric([], total_count) yield attribute_count attribute_read_count = GaugeMetricFamily( "attribute_read_count", 'Total number of read attributes') attribute_read_count.add_metric([], read_count) yield attribute_read_count spectrum_attribute_count = GaugeMetricFamily( "spectrum_attribute_count", 'Total number of spectrum attributes') spectrum_attribute_count.add_metric([], spectrum_count) yield spectrum_attribute_count image_attribute_count = GaugeMetricFamily( "image_attribute_count", 'Total number of image attributes') image_attribute_count.add_metric([], image_count) yield image_attribute_count not_managed = GaugeMetricFamily( "not_managed_attribute_count", 'Total number of not managed attributes') not_managed.add_metric([], not_managed_attribute_count) yield not_managed
from time import time from sanic import Blueprint from sanic.response import json from tango import Database, CmdArgType, DevFailed, ArgType, AttrDataFormat import conf from utils import buildurl, device_filtering from utils import buildurl from cache import getDeviceProxy, getAttributeProxy, getAttributeConfig, convertAttributeValue, getDeviceAttributeConfig from exceptions import HTTP501_NotImplemented from features import features api_rc3 = Blueprint("rc3") db = Database() tango_host = (db.get_db_host(), db.get_db_port()) @api_rc3.exception(DevFailed) async def tango_error(request, exception): """ Tango exceptions handler """ errors = [] for err in exception.args: errors.append({ "reason": err.reason, "description": err.desc, "severity": str(err.severity), "origin": err.origin }) return json({
class PiLCTriggerGateGenerator(Device): '''PiLCTriggerGateGenerator Provides high-level access to the PiLC Tango interface ''' PiLCFQDN = device_property(dtype=str, default_value='domain/family/member') exposure = attribute( dtype=int, format="%8d", label="Exposure", unit="ms", access=AttrWriteType.READ_WRITE, display_level=DispLevel.OPERATOR, doc="Exposure time in full 10ms steps", memorized=True, ) mode = attribute(dtype=Mode, label="Mode", access=AttrWriteType.READ_WRITE, display_level=DispLevel.OPERATOR, memorized=True, doc=""" 1 - free running 2 - triggered laser 3 - triggered laser & ccd """) def init_device(self): Device.init_device(self) try: self.pilc = DeviceProxy(self.PiLCFQDN) self.info_stream('Connected to PiLC: {:s}'.format(self.PiLCFQDN)) except: self.error_stream('Could not connect to PiLC: {:s}'.format( self.PiLCFQDN)) return self.set_state(DevState.OFF) self.set_state(DevState.ON) self.db = Database() try: attr = self.db.get_device_attribute_property( self.get_name(), ["exposure"]) self._exposure = int(attr["exposure"]["__value"][0]) except Exception: self._exposure = -1 try: attr = self.db.get_device_attribute_property( self.get_name(), ["mode"]) self._mode = int(attr["mode"]["__value"][0]) except Exception: self._mode = 0 def always_executed_hook(self): if self.pilc.ReadFPGA(0x06) > 0: self.set_state(DevState.MOVING) else: self.set_state(DevState.ON) # attribute read/write methods def read_exposure(self): return self._exposure def write_exposure(self, value): self._exposure = int(round(value / 10, 0) * 10) def read_mode(self): return self._mode def write_mode(self, value): self._mode = value # commands @command() def prepare(self): if self._exposure >= 40: shutter_gate_width = (self._exposure - 8) elif self._exposure >= 30: shutter_gate_width = (self._exposure - 7) elif self._exposure >= 20: shutter_gate_width = (self._exposure - 5) else: shutter_gate_width = self._exposure shutter_gate_delay = 0 keithley_gate_width = self._exposure keithley_gate_delay = 8 quantity = 1 self.debug_stream( 'Shutter gate width set to {:d} ms'.format(shutter_gate_width)) self.debug_stream( 'Shutter gate delay set to {:d} ms'.format(shutter_gate_delay)) self.debug_stream( 'Keithley gate width set to {:d} ms'.format(keithley_gate_width)) self.debug_stream( 'Keithley gate delay set to {:d} ms'.format(keithley_gate_delay)) self.debug_stream('Quantity set to {:d}'.format(quantity)) # define gate width in micorseconds self.pilc.WriteFPGA([0x03, int(shutter_gate_width * 1e3)]) # define gate delay in microseconds self.pilc.WriteFPGA([0x07, int(shutter_gate_delay * 1e3)]) # define keithley gate width in micorseconds self.pilc.WriteFPGA([0x09, int(keithley_gate_width * 1e3)]) # define keithley gate delay in microseconds self.pilc.WriteFPGA([0x0B, int(keithley_gate_delay * 1e3)]) # define gate quantity self.pilc.WriteFPGA([0x05, int(quantity)]) @command() def stop(self): self.debug_stream('Stop') self.pilc.WriteFPGA([0x01, 0]) @command() def start(self): self.debug_stream('Start in {:s} mode'.format(Mode(self._mode).name)) self.pilc.WriteFPGA([0x01, self._mode + 1]) @command() def acquire(self): self.debug_stream('Acquire') self.stop() self.prepare() self.start()
async def attribute_event_generator(self, configuration): config = json.loads(configuration) attr = config["attribute"] number_of_events = int(config["number_of_events"]) event_delay = config["event_delay"] polled = self.is_attribute_polled(attr) while number_of_events > 0: await asyncio.sleep(event_delay) # using _classname in calls to setattr and getattr due to name mangling # noqa E501 next_value = getattr(self, f"_TestDevice__{attr}") + 1 setattr(self, f"_TestDevice__{attr}", next_value) if not polled: self.push_change_event(attr, next_value) number_of_events -= 1 if __name__ == "__main__": db = Database() test_device = DbDevInfo() if "DEVICE_NAME" in os.environ: # DEVICE_NAME should be in the format domain/family/member test_device.name = os.environ["DEVICE_NAME"] else: # fall back to default name test_device.name = "test/device/1" test_device._class = "TestDevice" test_device.server = "TestDevice/test" db.add_server(test_device.server, test_device, with_dserver=True) TestDevice.run_server()
# coding: utf-8 """.""" from tango import Database # Get reference to tango database DB = Database() print('=' * 80) print('Database info:') print('=' * 80) print(DB.get_info()) print('=' * 80) print('Server list:') print('=' * 80) print(DB.get_server_list().value_string) print('')
def __initialize(args, db=None): args = args or sys.argv db = db or Database() klasses = [Bliss] # initialize logging fmt = '%(levelname)-8s %(asctime)s %(name)s: %(message)s' logging.basicConfig(level=logging.INFO, format=fmt) server_type, server_instance, server_name = utils.get_server_info(args) registered_servers = set(db.get_instance_name_list(server_type)) # check if server exists in database. If not, create it. if server_instance not in registered_servers: register_server(server_type, server_instance, db=db) device_map = utils.get_devices_from_server(args) # if in a jive wizard workflow, return no axis if not device_map.get('Bliss', ()): return klasses bliss_dev_name = device_map['Bliss'][0] props = db.get_device_property(bliss_dev_name, ('session_name',)) session_name = props.get('session_name', [None])[0] or server_instance this_dir = os.path.dirname(os.path.abspath(__file__)) suffix = '_ds.py' inits = [] shell_info = ns, session = load_shell(session_name) object_names = session.object_names or [] info = dict(server_type=server_type, server_instance=server_instance, session_name=session_name, device_map=device_map, manager_device_name=bliss_dev_name, object_names=object_names, shell_info=shell_info) for name in os.listdir(this_dir): if name.startswith('.'): continue if name.endswith(suffix): module_name = '{0}.{1}'.format(__package__, name[:-3]) _log.info('searching for init in %s...', module_name) try: module = __import(module_name) except ImportError as ie: _log.warning('failed to search for init in %s: %s', module_name, str(ie)) else: if hasattr(module, 'initialize_bliss') and \ callable(module.initialize_bliss): _log.info('found init in %s', module_name) try: mod_klasses = module.initialize_bliss(info, db=db) klasses.extend(mod_klasses) except Exception as e: _log.warning('failed to initialize %s: %s', module_name, str(e)) _log.debug('details:', exc_info=1) return klasses
# -*- coding: utf-8 -*- """Python script to register device""" from tango import Database, DbDevInfo # http://pytango.readthedocs.io/en/stable/database.html db = Database() # Define the tango Class served by this DServer device_info = DbDevInfo() device_info.name = 'sip_SDP/test/1' device_info._class = 'Test' device_info.server = 'Test/test' print('Adding device: %s' % device_info.name) # NOTE: This also adds the server defined by device_info.server to the db db.add_device(device_info)