Ejemplo n.º 1
0
    def test_alarm_propagation(self):
        device_name = '%s/sub1/1' % self.DOMAIN_NAME
        members_template = ['%s/capability/sub1cap1', '%s/capability/sub1cap2']
        members = [member % self.DOMAIN_NAME for member in members_template]

        self.add_members(device_name, 'tiles', members)
        dp = DeviceProxy(device_name)
        self.assertNotEqual(dp.state(), AttrQuality.ATTR_ALARM)
        member_dp = DeviceProxy(members[0])
        alarm_data = json.dumps({
            'name': 'an_attr',
            'min_alarm': '20',
            'max_alarm': '50'
        })
        member_dp.command_inout('set_attribute_alarm', alarm_data)
        member_dp.an_attr = 10
        attr = AttributeProxy(members[0] + '/an_attr')
        self.assertEqual(attr.read().quality, AttrQuality.ATTR_ALARM)
        self.assertEqual(member_dp.state(), PyTango._PyTango.DevState.ALARM)
        i = 0
        while (dp.state() != PyTango._PyTango.DevState.ALARM) and i < 3:
            sleep(1)
            i += 1

        self.assertEqual(dp.state(), PyTango._PyTango.DevState.ALARM)
Ejemplo n.º 2
0
 def add_members(self, device_name, group_name, members=None):
     dp = DeviceProxy(device_name)
     for member in members:
         data = json.dumps({
             'group_name': group_name,
             'device_name': member
         })
         dp.command_inout('add_member', data)
Ejemplo n.º 3
0
def cmdDevice(domain,deviceClass,deviceInstance):
    dev = DeviceProxy(domain+"/"+deviceClass+"/"+deviceInstance)
    json_data = request.get_json()
    cmd_name = json_data["cmd_name"]
    cmd_param = json_data["cmd_param"]
    if (cmd_param== "None"):
        result = dev.command_inout(cmd_name)
    else:
        result = dev.command_inout(cmd_name,cmd_param)
    return cmd_name
Ejemplo n.º 4
0
    def test_add_member(self):
        device_name = '%s/sub/1' % self.DOMAIN_NAME
        group_name = 'capabilities'
        # self.stop_device_server('Subarray_DS')
        # self.start_device_server('Subarray_DS')
        dp = DeviceProxy(device_name)
        dp.set_logging_level(5)
        member_device_name_1 = '%s/capability/sub1cap1' % self.DOMAIN_NAME
        data_1 = json.dumps({
            'group_name': group_name,
            'device_name': member_device_name_1
        })
        dp.command_inout('add_member', data_1)
        self.assertTrue(
            member_device_name_1 in dp.get_property(group_name)[group_name])

        member_device_name_2 = '%s/capability/sub1cap2' % self.DOMAIN_NAME
        data_2 = json.dumps({
            'group_name': group_name,
            'device_name': member_device_name_2
        })
        dp.command_inout('add_member', data_2)

        items = dp.get_property(group_name)[group_name]
        self.assertTrue(member_device_name_2 in items)
        self.assertEqual(len(items), 2)
        dp.command_inout('remove_member', data_2)

        items = dp.get_property(group_name)[group_name]
        self.assertFalse(member_device_name_2 in items)
        self.assertEqual(len(items), 1)

        dp.command_inout('remove_member', data_1)
        self.assertFalse(
            member_device_name_1 in dp.get_property(group_name)[group_name])
Ejemplo n.º 5
0
def _initCrate(macro, ctrl_obj, crate_nr):
    # It initializes all axis found in the same crate
    # than the target motor given.
    # We could have decided to initialize all motors in the controller.

    # Define axes range to re-initialize after reset
    # These are the motors in the same crate than the given motor
    first = crate_nr * 10
    last = first + 8
    macro.info('Initializing Crate number %s:' % crate_nr)
    macro.info('axes range [%s,%s]' % (first, last))

    # Get the alias for ALL motors for the controller
    motor_list = ctrl_obj.elementlist
    macro.debug("Element in controller: %s" % repr(motor_list))

    # Crate a proxy to each element and
    # get the axis for each of them
    for alias in motor_list:
        m = DeviceProxy(alias)
        a = int(m.get_property('axis')['axis'][0])
        # Execute init command for certain motors:
        if first <= a <= last:
            macro.debug('alias: %s' % alias)
            macro.debug('device name: %s' % m.name())
            macro.debug('axis number: %s' % a)
            macro.info("Initializing %s..." % alias)
            try:
                m.command_inout('Init')
            # HOTFIX!!! only if offsets are lost 24/12/2016
            # print 'IMPORTANT: OVERWRITTING centx/centy offsets!'
            # if alias == 'centx':
            #    centx_offset = -4.065240223463690
            #    m['offset'] = centx_offset
            #    print 'centx offset overwritten: %f' % centx_offset
            # if alias == 'centy':
            #    centy_offset = -2.759407821229050
            #    m['offset'] = centy_offset
            #    print 'centy offset overwritten: %f' % centy_offset

            except Exception:
                macro.error('axis %s cannot be initialized' % alias)
Ejemplo n.º 6
0
def command_inout(command):
    print("in command_inout")
    arg = request.get_json()
    print(arg)
    try:
        p = DeviceProxy("sys/tg_test/1")
        encodedArg = arg  #encodeArg(command,arg,p)
        if (encodedArg == 'null'):
            result = p.command_inout(command)
        else:
            result = p.command_inout(command, encodedArg)
        if isinstance(result, numpy.ndarray):
            result = result.tolist()
        elif isinstance(result, list):
            result = re.sub(r"([\d.]+)", r"'\1'", result.__str__())
        if app.testing:
            print(json.dumps(result))
        return jsonify(json.dumps(result))
    except (CommunicationFailed, ConnectionFailed, DevFailed) as e:
        return jsonify(handleException(e))
Ejemplo n.º 7
0
class TangoTestContext(object):
    """ Context to run a device without a database."""

    nodb = "#dbase=no"
    command = "{0} {1} -ORBendPoint giop:tcp::{2} -file={3}"
    connect_time = 6.0

    def __init__(self, device, device_cls=None, server_name=None,
                 instance_name=None, device_name=None, properties={},
                 db=None, port=0, debug=5, daemon=False, process=False):
        """Inititalize the context to run a given device."""
        # Argument
        tangoclass = device.__name__
        if not server_name:
            server_name = tangoclass
        if not instance_name:
            instance_name = server_name.lower()
        if not device_name:
            device_name = 'test/nodb/' + server_name.lower()
        if not port:
            port = get_port()
        if db is None:
            _, db = tempfile.mkstemp()
        # Attributes
        self.db = db
        self.port = port
        self.device_name = device_name
        self.server_name = "/".join(("dserver", server_name, instance_name))
        self.host = "{0}:{1}/".format(platform.node(), self.port)
        self.device = self.server = None
        # File
        self.generate_db_file(server_name, instance_name, device_name,
                              tangoclass, properties)
        # Command args
        string = self.command.format(server_name, instance_name, port, db)
        string += " -v{0}".format(debug) if debug else ""
        cmd_args = string.split()
        # Target and arguments
        if device_cls:
            target = run
            args = ({tangoclass: (device_cls, device)}, cmd_args)
        elif not hasattr(device, 'run_server'):
            target = run
            args = ((device,), cmd_args)
        else:
            target = device.run_server
            args = (cmd_args,)
        # Thread
        cls = Process if process else Thread
        self.thread = cls(target=target, args=args)
        self.thread.daemon = daemon

    def generate_db_file(self, server, instance, device,
                         tangoclass=None, properties={}):
        """Generate a database file corresponding to the given arguments."""
        if not tangoclass:
            tangoclass = server
        # Open the file
        with open(self.db, 'w') as f:
            f.write("/".join((server, instance, "DEVICE", tangoclass)))
            f.write(': "' + device + '"\n')
        # Create database
        db = Database(self.db)
        # Patched the property dict to avoid a PyTango bug
        patched = dict((key, value if value != '' else ' ')
                       for key, value in properties.items())
        # Write properties
        db.put_device_property(device, patched)
        return db

    def get_device_access(self):
        """Return the full device name."""
        return self.host+self.device_name+self.nodb

    def get_server_access(self):
        """Return the full server name."""
        return self.host+self.server_name+self.nodb

    def start(self):
        """Run the server."""
        self.thread.start()
        self.connect()
        return self

    @retry(connect_time, [ConnectionFailed, DevFailed])
    def connect(self):
        self.device = DeviceProxy(self.get_device_access())
        self.device.ping()
        self.server = DeviceProxy(self.get_server_access())
        self.server.ping()

    def stop(self, timeout=None):
        """Kill the server."""
        if self.server:
            self.server.command_inout('Kill')
        self.thread.join(timeout)
        os.unlink(self.db)

    def join(self, timeout=None):
        self.thread.join(timeout)

    def __enter__(self):
        """Enter method for context support."""
        if not self.thread.is_alive():
            self.start()
        return self.device

    def __exit__(self, exc_type, exception, trace):
        """Exit method for context support."""
        self.stop()
Ejemplo n.º 8
0
class MgConf:
    def __init__(self, poolName, mntgrpName, flagClear):
        self.db = Database()
        #
        # the pool for the Mg
        #
        try:
            self.poolMg = DeviceProxy(poolName)
        except Exception as e:
            Except.print_exception(e)
            print("failed to get proxy to ", poolName)
            sys.exit(255)
        #
        # find the MG
        #
        try:
            self.mg = DeviceProxy(mntgrpName)
        except Exception:
            lst = [mntgrpName, 'exp_t01', 'exp_c01', 'exp_c02']
            self.poolMg.command_inout('CreateMeasurementGroup', lst)
            self.mg = DeviceProxy(mntgrpName)

        if not flagClear:
            self.hsh = json.loads(self.mg.Configuration)
            self.masterTimer = self.findMasterTimer()
            self.index = len(self.mg.ElementList)
        else:
            self.hsh = {}
            self.hsh[u'controllers'] = {}
            self.hsh[u'description'] = "Measurement Group"
            self.hsh[u'label'] = mntgrpName
            self.index = 0

    def findMasterTimer(self):
        if not HasyUtils.versionSardanaNewMg():
            self.findMasterTimerD8()
        else:
            self.findMasterTimerD9()

    def findMasterTimerD8(self):
        for ctrl in self.hsh[u'controllers']:
            Channels = self.hsh[u'controllers'][ctrl][u'units'][u'0'][
                u'channels']
            for chan in Channels:
                if chan.find('dgg2') > 0:
                    temp = chan
                    if temp.find('0000') >= 0:
                        lst = temp.split("/")
                        temp = "/".join(lst[1:])
                    masterTimer = self.db.get_alias(str(temp))
                    return masterTimer
        raise ('MgUtils.findMasterTimer', "No timer found")

    def findMasterTimerD9(self):

        temp = self.hsh[u'timer']
        if temp.find('0000') >= 0:
            lst = temp.split("/")
            #
            # tango://haso113u.desy.de:10000/expchan/dgg2_d1_01/1
            #
            if lst[0].lower() == 'tango:':
                temp = "/".join(lst[3:])
            else:
                temp = "/".join(lst[1:])
            #
            # expchan/dgg2_d1_01/1
            #
            masterTimer = self.db.get_alias(str(temp))
        return masterTimer

    def findDeviceController(self, device):
        """
        returns the controller that belongs to a device
        """

        lst = []
        if self.poolMg.ExpChannelList is not None:
            lst = self.poolMg.ExpChannelList
        ctrl = None
        for elm in lst:
            chan = json.loads(elm)
            # chan:
            # {
            # u'axis': 17,
            # u'controller':
            # u'haso107klx:10000/controller/sis3820ctrl/sis3820_exp',
            # u'full_name': u'haso107klx:10000/expchan/sis3820_exp/17',
            # u'id': 146,
            # u'instrument': u'',
            # u'interfaces': [u'Object', u'PoolObject', u'Element',
            # u'ExpChannel', u'PoolElement', u'CTExpChannel', u'Acquirable'],
            # u'manager': u'exp_pool01',
            # u'name': u'exp_c17',
            # u'parent': u'sis3820_exp',
            # u'pool': u'exp_pool01',
            # u'source': u'haso107klx:10000/expchan/sis3820_exp/17/value',
            # u'type': u'CTExpChannel',
            # u'unit': u'0',
            # }
            if device == chan['name']:
                ctrl = chan['controller']
                break
        if ctrl is None and device.find("adc") >= 0:
            ctrl = os.getenv("TANGO_HOST") + "/" + \
                "controller/hasylabadcctrl/hasyadcctrl"
        elif ctrl is None and device.find("vfc") >= 0:
            ctrl = os.getenv("TANGO_HOST") + "/" + \
                "controller/vfcadccontroller/hasyvfcadcctrl"
        return ctrl

    def findFullDeviceName(self, device):
        """
          input: exp_c01
          returns: expchan/hasylabvirtualcounterctrl/1
        """

        lst = self.poolMg.AcqChannelList
        argout = None
        for elm in lst:
            chan = json.loads(elm)
            if device == chan['name']:
                #
                # from: expchan/hasysis3820ctrl/1/value
                # to:   expchan/hasysis3820ctrl/1
                #
                arr = chan['full_name'].split("/")
                argout = "/".join(arr[0:-1])
        if argout is None:
            print("Error with device")
            print(device)
            raise Exception('MgUtils.findFullDeviceName, %s' % device,
                            "failed to find  %s" % device)
        return argout

    def updateConfiguration(self):
        """
        json-dump the dictionary self.hsh to the Mg configuration
        """
        self.mg.Configuration = json.dumps(self.hsh)

    def addTimer(self, device):
        if not HasyUtils.versionSardanaNewMg():
            self.addTimerD8(device)
        else:
            self.addTimerD9(device)

    def addTimerD8(self, device):
        """
        add a timer to the Mg
        device: exp_t01
        """
        ctrl = self.findDeviceController(device)
        if ctrl not in self.hsh[u'controllers'].keys():
            self.masterTimer = device
            self.hsh[u'monitor'] = self.findFullDeviceName(device)
            self.hsh[u'timer'] = self.findFullDeviceName(device)
            self.hsh[u'controllers'][ctrl] = {}
            self.hsh[u'controllers'][ctrl][u'units'] = {}
            self.hsh[u'controllers'][ctrl][u'units'][u'0'] = {}
            self.hsh[u'controllers'][ctrl][u'units'][u'0'][u'channels'] = {}
            self.hsh[u'controllers'][ctrl][u'units'][u'0'][u'id'] = 0
            self.hsh[u'controllers'][ctrl][u'units'][u'0'][u'monitor'] = \
                self.findFullDeviceName(device)
            self.hsh[u'controllers'][ctrl][u'units'][u'0'][u'timer'] = \
                self.findFullDeviceName(device)
            self.hsh[u'controllers'][ctrl][u'units'][u'0'][u'trigger_type'] = 0

        ctrlChannels = self.hsh[u'controllers'][ctrl][u'units'][u'0'][
            u'channels']
        fullDeviceName = self.findFullDeviceName(device)
        if fullDeviceName not in ctrlChannels.keys():
            print("adding index", self.index, device)
            dct = {}
            dct[u'_controller_name'] = str(ctrl)
            dct[u'_unit_id'] = u'0'
            dct[u'conditioning'] = u''
            dct[u'data_type'] = u'float64'
            dct[u'data_units'] = u'No unit'
            dct[u'enabled'] = True
            dct[u'full_name'] = fullDeviceName
            dct[u'index'] = self.index
            self.index += 1
            dct[u'instrument'] = None
            dct[u'label'] = str(device)
            dct[u'name'] = str(device)
            dct[u'ndim'] = 0
            dct[u'nexus_path'] = u''
            dct[u'normalization'] = 0
            dct[u'output'] = True
            dct[u'plot_axes'] = []
            dct[u'plot_type'] = 0
            dct[u'shape'] = []
            dct[u'source'] = dct['full_name'] + "/value"
            ctrlChannels[fullDeviceName] = dct

    def addTimerD9(self, device):
        """
        add a timer to the Mg
        device: exp_t01
        """
        ctrl = self.findDeviceController(device)
        if ctrl not in self.hsh[u'controllers'].keys():
            self.masterTimer = device
            self.hsh[u'monitor'] = self.findFullDeviceName(device)
            self.hsh[u'timer'] = self.findFullDeviceName(device)
            self.hsh[u'controllers'][ctrl] = {}
            self.hsh[u'controllers'][ctrl][u'synchronizer'] = "software"
            self.hsh[u'controllers'][ctrl][u'channels'] = {}
            self.hsh[u'controllers'][ctrl][u'id'] = 0
            self.hsh[u'controllers'][ctrl][u'monitor'] = \
                self.findFullDeviceName(device)
            self.hsh[u'controllers'][ctrl][u'timer'] = \
                self.findFullDeviceName(device)
            self.hsh[u'controllers'][ctrl][u'trigger_type'] = 0

        ctrlChannels = self.hsh[u'controllers'][ctrl][u'channels']
        fullDeviceName = self.findFullDeviceName(device)
        if fullDeviceName not in ctrlChannels.keys():
            print("adding index", self.index, device)
            dct = {}
            dct[u'conditioning'] = u''
            dct[u'enabled'] = True
            dct[u'full_name'] = fullDeviceName
            dct[u'index'] = self.index
            self.index += 1
            dct[u'label'] = str(device)
            dct[u'name'] = str(device)
            dct[u'ndim'] = 0
            dct[u'normalization'] = 0
            dct[u'output'] = True
            dct[u'plot_axes'] = []
            dct[u'plot_type'] = 0
            dct[u'source'] = dct['full_name'] + "/value"
            ctrlChannels[fullDeviceName] = dct

    def addExtraTimer(self, device):
        if not HasyUtils.versionSardanaNewMg():
            self.addExtraTimerD8(device)
        else:
            self.addExtraTimerD9(device)

    #
    # add an extra timer to the measurement group
    #
    def addExtraTimerD8(self, device):
        """ device: exp_t01"""
        ctrl = self.findDeviceController(device)
        if ctrl not in self.hsh[u'controllers'].keys():
            self.hsh[u'controllers'][ctrl] = {}
            self.hsh[u'controllers'][ctrl][u'units'] = {}
            self.hsh[u'controllers'][ctrl][u'units'][u'0'] = {}
            self.hsh[u'controllers'][ctrl][u'units'][u'0'][u'channels'] = {}
            self.hsh[u'controllers'][ctrl][u'units'][u'0'][u'id'] = 0
            self.hsh[u'controllers'][ctrl][u'units'][u'0'][u'monitor'] = \
                self.findFullDeviceName(device)
            self.hsh[u'controllers'][ctrl][u'units'][u'0'][u'timer'] = \
                self.findFullDeviceName(device)
            self.hsh[u'controllers'][ctrl][u'units'][u'0'][u'trigger_type'] = 0

        ctrlChannels = self.hsh[u'controllers'][ctrl][u'units'][u'0'][
            u'channels']
        fullDeviceName = self.findFullDeviceName(device)
        if fullDeviceName not in ctrlChannels.keys():
            dct = {}
            dct[u'_controller_name'] = str(ctrl)
            dct[u'_unit_id'] = u'0'
            dct[u'conditioning'] = u''
            dct[u'data_type'] = u'float64'
            dct[u'data_units'] = u'No unit'
            dct[u'enabled'] = True
            dct[u'full_name'] = fullDeviceName
            dct[u'index'] = self.index
            self.index += 1
            dct[u'instrument'] = None
            dct[u'label'] = str(device)
            dct[u'name'] = str(device)
            dct[u'ndim'] = 0
            dct[u'nexus_path'] = u''
            dct[u'normalization'] = 0
            dct[u'output'] = True
            dct[u'plot_axes'] = []
            dct[u'plot_type'] = 0
            dct[u'shape'] = []
            dct[u'source'] = dct['full_name'] + "/value"
            ctrlChannels[fullDeviceName] = dct

    #
    # add an extra timer to the measurement group
    #
    def addExtraTimerD9(self, device):
        """ device: exp_t01"""
        ctrl = self.findDeviceController(device)
        if ctrl not in self.hsh[u'controllers'].keys():
            self.hsh[u'controllers'][ctrl] = {}
            self.hsh[u'controllers'][ctrl][u'synchronizer'] = "software"
            self.hsh[u'controllers'][ctrl][u'channels'] = {}
            self.hsh[u'controllers'][ctrl][u'id'] = 0
            self.hsh[u'controllers'][ctrl][u'monitor'] = \
                self.findFullDeviceName(device)
            self.hsh[u'controllers'][ctrl][u'timer'] = \
                self.findFullDeviceName(device)
            self.hsh[u'controllers'][ctrl][u'trigger_type'] = 0

        ctrlChannels = self.hsh[u'controllers'][ctrl][u'channels']
        fullDeviceName = self.findFullDeviceName(device)
        if fullDeviceName not in ctrlChannels.keys():
            dct = {}
            dct[u'conditioning'] = u''
            dct[u'enabled'] = True
            dct[u'full_name'] = fullDeviceName
            dct[u'index'] = self.index
            self.index += 1
            dct[u'label'] = str(device)
            dct[u'name'] = str(device)
            dct[u'ndim'] = 0
            dct[u'normalization'] = 0
            dct[u'output'] = True
            dct[u'plot_axes'] = []
            dct[u'plot_type'] = 0
            dct[u'source'] = dct['full_name'] + "/value"
            ctrlChannels[fullDeviceName] = dct

    def addCounter(self, device, flagDisplay, flagOutput):
        if not HasyUtils.versionSardanaNewMg():
            self.addCounterD8(device, flagDisplay, flagOutput)
        else:
            self.addCounterD9(device, flagDisplay, flagOutput)

    #
    # add a counter to the measurement group
    #
    def addCounterD8(self, device, flagDisplay, flagOutput):

        if device.find('sca_') == 0:
            return self.addSCA(device, flagDisplay, flagOutput)

        ctrl = self.findDeviceController(device)
        if ctrl not in self.hsh[u'controllers'].keys():
            print("MgUtils.addCounter adding controller ", ctrl)
            self.hsh[u'controllers'][ctrl] = {}
            self.hsh[u'controllers'][ctrl][u'units'] = {}
            self.hsh[u'controllers'][ctrl][u'units'][u'0'] = {}
            self.hsh[u'controllers'][ctrl][u'units'][u'0'][u'channels'] = {}
            self.hsh[u'controllers'][ctrl][u'units'][u'0'][u'id'] = 0
            self.hsh[u'controllers'][ctrl][u'units'][u'0'][u'monitor'] = \
                self.findFullDeviceName(self.masterTimer)
            self.hsh[u'controllers'][ctrl][u'units'][u'0'][u'timer'] = \
                self.findFullDeviceName(self.masterTimer)
            self.hsh[u'controllers'][ctrl][u'units'][u'0'][u'trigger_type'] = 0

        ctrlChannels = self.hsh[u'controllers'][ctrl][u'units'][u'0'][
            u'channels']
        fullDeviceName = self.findFullDeviceName(device)
        if fullDeviceName not in ctrlChannels.keys():
            print("adding index", self.index, device)
            dct = {}
            dct[u'_controller_name'] = str(ctrl)
            dct[u'_unit_id'] = u'0'
            dct[u'conditioning'] = u''
            dct[u'data_type'] = u'float64'
            dct[u'data_units'] = u'No unit'
            dct[u'enabled'] = True
            dct[u'full_name'] = fullDeviceName
            dct[u'index'] = self.index
            self.index += 1
            dct[u'instrument'] = u''
            dct[u'label'] = str(device)
            dct[u'name'] = str(device)
            dct[u'ndim'] = 0
            dct[u'nexus_path'] = u''
            dct[u'normalization'] = 0
            if flagOutput:
                dct[u'output'] = True
            else:
                dct[u'output'] = False
            dct[u'plot_axes'] = [u'<mov>']
            if flagDisplay:
                dct[u'plot_type'] = 1
            else:
                dct[u'plot_type'] = 0
            dct[u'shape'] = []
            dct[u'source'] = dct['full_name'] + "/value"
            ctrlChannels[fullDeviceName] = dct

    #
    # add a counter to the measurement group
    #
    def addCounterD9(self, device, flagDisplay, flagOutput):

        if device.find('sca_') == 0:
            return self.addSCA(device, flagDisplay, flagOutput)

        ctrl = self.findDeviceController(device)
        if ctrl not in self.hsh[u'controllers'].keys():
            print("MgUtils.addCounter adding controller ", ctrl)
            self.hsh[u'controllers'][ctrl] = {}
            self.hsh[u'controllers'][ctrl][u'synchronizer'] = "software"
            self.hsh[u'controllers'][ctrl][u'channels'] = {}
            self.hsh[u'controllers'][ctrl][u'id'] = 0
            self.hsh[u'controllers'][ctrl][u'monitor'] = \
                self.findFullDeviceName(device)
            self.hsh[u'controllers'][ctrl][u'timer'] = \
                self.findFullDeviceName(device)
            self.hsh[u'controllers'][ctrl][u'trigger_type'] = 0

        ctrlChannels = self.hsh[u'controllers'][ctrl][u'channels']
        fullDeviceName = self.findFullDeviceName(device)
        if fullDeviceName not in ctrlChannels.keys():
            print("adding index", self.index, device)
            dct = {}
            dct[u'conditioning'] = u''
            dct[u'enabled'] = True
            dct[u'full_name'] = fullDeviceName
            dct[u'index'] = self.index
            self.index += 1
            dct[u'label'] = str(device)
            dct[u'name'] = str(device)
            dct[u'ndim'] = 0
            dct[u'normalization'] = 0
            if flagOutput:
                dct[u'output'] = True
            else:
                dct[u'output'] = False
            dct[u'plot_axes'] = [u'<mov>']
            if flagDisplay:
                dct[u'plot_type'] = 1
            else:
                dct[u'plot_type'] = 0
            dct[u'source'] = dct['full_name'] + "/value"
            ctrlChannels[fullDeviceName] = dct

    def addMCA(self, device):
        if not HasyUtils.versionSardanaNewMg():
            self.addMCAD8(device)
        else:
            self.addMCAD9(device)

    #
    # add a MCA to the measurement group
    #
    def addMCAD8(self, device):
        ctrl = self.findDeviceController(device)
        if ctrl not in self.hsh[u'controllers'].keys():
            print("MgUtils.addMCA adding controller ", ctrl)
            self.hsh[u'controllers'][ctrl] = {}
            self.hsh[u'controllers'][ctrl][u'units'] = {}
            self.hsh[u'controllers'][ctrl][u'units'][u'0'] = {}
            self.hsh[u'controllers'][ctrl][u'units'][u'0'][u'channels'] = {}
            self.hsh[u'controllers'][ctrl][u'units'][u'0'][u'id'] = 0
            self.hsh[u'controllers'][ctrl][u'units'][u'0'][u'monitor'] = \
                self.findFullDeviceName(self.masterTimer)
            self.hsh[u'controllers'][ctrl][u'units'][u'0'][u'timer'] = \
                self.findFullDeviceName(self.masterTimer)
            self.hsh[u'controllers'][ctrl][u'units'][u'0'][u'trigger_type'] = 0

        ctrlChannels = self.hsh[u'controllers'][ctrl][u'units'][u'0'][
            u'channels']
        fullDeviceName = self.findFullDeviceName(device)
        if fullDeviceName not in ctrlChannels.keys():
            print("adding index", self.index, device)
            proxy = DeviceProxy(str(fullDeviceName))
            dct = {}
            dct[u'_controller_name'] = str(ctrl)
            dct[u'_unit_id'] = u'0'
            dct[u'conditioning'] = u''
            dct[u'data_type'] = u'float64'
            dct[u'data_units'] = u'No unit'
            dct[u'enabled'] = True
            dct[u'full_name'] = fullDeviceName
            dct[u'index'] = self.index
            self.index += 1
            dct[u'instrument'] = None
            dct[u'label'] = str(device)
            dct[u'name'] = str(device)
            dct[u'ndim'] = 1
            dct[u'nexus_path'] = u''
            dct[u'normalization'] = 0
            dct[u'output'] = True
            dct[u'plot_axes'] = []
            dct[u'plot_type'] = 0
            dct[u'shape'] = [proxy.DataLength]
            dct[u'source'] = fullDeviceName + "/Value"
            ctrlChannels[fullDeviceName] = dct

    #
    # add a MCA to the measurement group
    #
    def addMCAD9(self, device):
        ctrl = self.findDeviceController(device)
        if ctrl not in self.hsh[u'controllers'].keys():
            print("MgUtils.addMCA adding controller ", ctrl)
            self.hsh[u'controllers'][ctrl] = {}
            self.hsh[u'controllers'][ctrl][u'synchronizer'] = "software"
            self.hsh[u'controllers'][ctrl][u'channels'] = {}
            self.hsh[u'controllers'][ctrl][u'id'] = 0
            self.hsh[u'controllers'][ctrl][u'monitor'] = \
                self.findFullDeviceName(device)
            self.hsh[u'controllers'][ctrl][u'timer'] = \
                self.findFullDeviceName(device)
            self.hsh[u'controllers'][ctrl][u'trigger_type'] = 0

        ctrlChannels = self.hsh[u'controllers'][ctrl][u'channels']
        fullDeviceName = self.findFullDeviceName(device)
        if fullDeviceName not in ctrlChannels.keys():
            print("adding index", self.index, device)
            # proxy =
            DeviceProxy(str(fullDeviceName))
            dct = {}
            dct[u'conditioning'] = u''
            dct[u'enabled'] = True
            dct[u'full_name'] = fullDeviceName
            dct[u'index'] = self.index
            self.index += 1
            dct[u'label'] = str(device)
            dct[u'name'] = str(device)
            dct[u'ndim'] = 1
            dct[u'normalization'] = 0
            dct[u'output'] = True
            dct[u'plot_axes'] = [u'<mov>']
            dct[u'plot_type'] = 0
            dct[u'source'] = fullDeviceName + "/Value"
            ctrlChannels[fullDeviceName] = dct

    def addPilatus(self, device):
        if not HasyUtils.versionSardanaNewMg():
            self.addPilatusD8(device)
        else:
            self.addPilatusD9(device)

    #
    # add a MCA to the measurement group
    #
    def addPilatusD8(self, device):
        ctrl = self.findDeviceController(device)
        if ctrl not in self.hsh[u'controllers'].keys():
            print("MgUtils.addPilatus adding controller ", ctrl)
            self.hsh[u'controllers'][ctrl] = {}
            self.hsh[u'controllers'][ctrl][u'units'] = {}
            self.hsh[u'controllers'][ctrl][u'units'][u'0'] = {}
            self.hsh[u'controllers'][ctrl][u'units'][u'0'][u'channels'] = {}
            self.hsh[u'controllers'][ctrl][u'units'][u'0'][u'id'] = 0
            self.hsh[u'controllers'][ctrl][u'units'][u'0'][u'monitor'] = \
                self.findFullDeviceName(self.masterTimer)
            self.hsh[u'controllers'][ctrl][u'units'][u'0'][u'timer'] = \
                self.findFullDeviceName(self.masterTimer)
            self.hsh[u'controllers'][ctrl][u'units'][u'0'][u'trigger_type'] = 0

        ctrlChannels = self.hsh[u'controllers'][ctrl][u'units'][u'0'][
            u'channels']
        fullDeviceName = self.findFullDeviceName(device)
        if fullDeviceName not in ctrlChannels.keys():
            print("adding index", self.index, device)
            # proxy =
            DeviceProxy(str(fullDeviceName))
            dct = {}
            dct[u'_controller_name'] = str(ctrl)
            dct[u'_unit_id'] = u'0'
            dct[u'conditioning'] = u''
            dct[u'enabled'] = True
            dct[u'full_name'] = fullDeviceName
            dct[u'index'] = self.index
            self.index += 1
            dct[u'instrument'] = u''
            dct[u'label'] = str(device)
            dct[u'name'] = str(device)
            dct[u'ndim'] = 2
            dct[u'nexus_path'] = u''
            dct[u'normalization'] = 0
            dct[u'output'] = True
            dct[u'plot_axes'] = []
            dct[u'plot_type'] = 0
            dct[u'source'] = fullDeviceName + "/Value"
            ctrlChannels[fullDeviceName] = dct

    #
    # add a Pilatus to the measurement group
    #
    def addPilatusD9(self, device):
        ctrl = self.findDeviceController(device)
        if ctrl not in self.hsh[u'controllers'].keys():
            print("MgUtils.addPilatus adding controller ", ctrl)
            self.hsh[u'controllers'][ctrl] = {}
            self.hsh[u'controllers'][ctrl][u'synchronizer'] = "software"
            self.hsh[u'controllers'][ctrl][u'channels'] = {}
            self.hsh[u'controllers'][ctrl][u'id'] = 0
            self.hsh[u'controllers'][ctrl][u'monitor'] = \
                self.findFullDeviceName(device)
            self.hsh[u'controllers'][ctrl][u'timer'] = \
                self.findFullDeviceName(device)
            self.hsh[u'controllers'][ctrl][u'trigger_type'] = 0

        ctrlChannels = self.hsh[u'controllers'][ctrl][u'channels']
        fullDeviceName = self.findFullDeviceName(device)
        if fullDeviceName not in ctrlChannels.keys():
            print("adding index", self.index, device)
            # proxy =
            DeviceProxy(str(fullDeviceName))
            dct = {}
            dct[u'conditioning'] = u''
            dct[u'enabled'] = True
            dct[u'full_name'] = fullDeviceName
            dct[u'index'] = self.index
            self.index += 1
            dct[u'label'] = str(device)
            dct[u'name'] = str(device)
            dct[u'ndim'] = 2
            dct[u'normalization'] = 0
            dct[u'output'] = True
            dct[u'plot_axes'] = [u'<mov>']
            dct[u'plot_type'] = 0
            dct[u'source'] = fullDeviceName + "/Value"
            ctrlChannels[fullDeviceName] = dct

    def parseSCA(self, name):
        """
        name: sca_exp_mca01_100_200, returns ['exp_mca01', '100', '200']
        """
        lst = name.split('_')
        return [lst[1] + '_' + lst[2], lst[3], lst[4]]

    def _getMcaName(self, mcaSardanaDeviceAlias):
        """
        input: sardana device name alias
        output: the MCA Tango server name which is used by the Sardana device
        """
        try:
            proxy = DeviceProxy(mcaSardanaDeviceAlias)
        except DevFailed as e:
            Except.re_throw_exception(
                e, "MgUtils",
                "failed to create proxy to %s " % mcaSardanaDeviceAlias,
                "MgUtils._gHeMcaName")
        return proxy.TangoDevice

    def _addSca(self, device):
        """
        Input: device: sca_exp_mca01_100_200
        Returns full controller name, e.g.:
        haso107klx:10000/controller/hasscactrl/sca_exp_mca01_100_200
        Creates a HasySca controller and creates a device for this controller,
        There is only one device per controller
        """
        mca, roiMin, roiMax = self.parseSCA(device)
        #
        # find the tango device name which is used my the sardana device
        #
        tgMca = self._getMcaName(mca)
        #
        # sca_exp_mca01_100_200_ctrl
        #
        ctrlAlias = device + "_ctrl"
        #
        # see whether the controller exists already
        #

        lst = self.poolMg.ControllerList
        ctrlFullName = None
        for elm in lst:
            chan = json.loads(elm)
            if ctrlAlias == chan['name']:
                ctrlFullName = chan['full_name']
                break
        #
        # if the controller does not exist, create it
        #
        proxy = DeviceProxy(tgMca)
        dataLength = proxy.DataLength
        if int(roiMax) >= dataLength:
            raise Exception(
                "MgUtils._addSca %s " % device,
                "roiMax %d  >= datalength %d " %
                (int(roiMax), int(dataLength)))
        if int(roiMin) >= dataLength:
            raise Exception(
                "MgUtils._addSca %s " % device,
                "roiMin %d  >= datalength %d " % (int(roiMin), dataLength))

        if ctrlFullName is None:
            lst = [
                'CTExpChannel', 'HasyScaCtrl.py', 'HasyScaCtrl', ctrlAlias,
                "mca", tgMca, "roi1", roiMin, "roi2", roiMax
            ]
            print("MgUtils._addSca", lst)
            try:
                self.poolMg.CreateController(lst)
            except DevFailed as e:
                Except.print_exception(e)
                # print "failed to get proxy to ", poolName
                sys.exit(255)

            lst = self.poolMg.ControllerList
            for elm in lst:
                chan = json.loads(elm)
                if ctrlAlias == chan['name']:
                    ctrlFullName = chan['full_name']
                    break
        if ctrlFullName is None:
            raise Exception('MgUtils._addSca',
                            "failed to make controller for %s" % device)

        #
        # see whether the SCA device exists
        #
        lst = self.poolMg.ExpChannelList
        flag = False
        for elm in lst:
            chan = json.loads(elm)
            if device == chan['name']:
                flag = True
                break

        if not flag:
            #
            # "CTExpChannel","HasyScaCtrl","1","sca_exp_mca01_100_200"
            #
            lst = ["CTExpChannel", ctrlAlias, "1", device]
            self.poolMg.CreateElement(lst)

        return ctrlFullName

    def makeScaControllerForPseudoCounter(self, device):
        """
        Input: device: sca_exp_mca01_100_200
        Returns full controller name, e.g.:
        haso107klx:10000/controller/mca2scactrl/sca_exp_mca01_100_200_ctrl
        """
        mca, roiMin, roiMax = self.parseSCA(device)

        ctrlAlias = device + "_ctrl"
        #
        # see whether the controller exists already
        #
        lst = self.poolMg.ControllerList
        for elm in lst:
            chan = json.loads(elm)
            if ctrlAlias == chan['name']:
                return chan['full_name']
        lst = [
            'PseudoCounter', 'MCA2SCACtrl.py', 'MCA2SCACtrl', device + "_ctrl",
            'mca=' + self.findFullDeviceName(mca), 'sca=' + device
        ]

        # print "MgUutils.makeSardanaController", lst
        self.poolMg.CreateController(lst)
        #
        # now it has been created.
        # go through the list again an return the full controller name
        #
        lst = self.poolMg.ControllerList
        for elm in lst:
            chan = json.loads(elm)
            if ctrlAlias == chan['name']:
                #
                # set the ROIs
                #
                proxy = DeviceProxy(device)
                proxy.Roi1 = int(roiMin)
                proxy.Roi2 = int(roiMax)
                return chan['full_name']
        raise Exception('MgUtils.makeController',
                        "failed to make controller for %s" % device)

    def addSCA(self, device, flagDisplay, flagOutput):
        if not HasyUtils.versionSardanaNewMg():
            self.addSCAD8(device, flagDisplay, flagOutput)
        else:
            self.addSCAD9(device, flagDisplay, flagOutput)

    def addSCAD8(self, device, flagDisplay, flagOutput):
        """
        add a SCA to the measurement group
          input: device, e.g. sca_exp_mca01_100_200
        """
        if device.find('sca_') != 0:
            print("MgUtils.addSCA: '%s' does not begin with 'sca_'," % device)
            return False

        #
        # there is one element per controller
        #
        fullCtrlName = self._addSca(device)
        if fullCtrlName not in self.hsh[u'controllers'].keys():
            print("MgUtils.addSca adding controller ", fullCtrlName)
            self.hsh[u'controllers'][fullCtrlName] = {}
            self.hsh[u'controllers'][fullCtrlName][u'units'] = {}
            self.hsh[u'controllers'][fullCtrlName][u'units'][u'0'] = {}
            self.hsh[u'controllers'][fullCtrlName][u'units'][u'0'][
                u'channels'] = {}
            self.hsh[u'controllers'][fullCtrlName][u'units'][u'0'][u'id'] = 0
            self.hsh[u'controllers'][fullCtrlName][u'units'][u'0'][
                u'monitor'] = self.findFullDeviceName(self.masterTimer)
            self.hsh[u'controllers'][fullCtrlName][u'units'][u'0'][
                u'timer'] = self.findFullDeviceName(self.masterTimer)
            self.hsh[u'controllers'][fullCtrlName][u'units'][u'0'][
                u'trigger_type'] = 0

        ctrlChannels = self.hsh[u'controllers'][fullCtrlName][u'units'][u'0'][
            u'channels']
        if not self.findFullDeviceName(device) in ctrlChannels.keys():
            print("adding index", self.index, device)
            dct = {}
            dct[u'_controller_name'] = str(fullCtrlName)
            dct[u'_unit_id'] = u'0'
            dct[u'conditioning'] = u''
            dct[u'enabled'] = True
            dct[u'full_name'] = self.findFullDeviceName(device)
            dct[u'index'] = self.index
            self.index += 1
            dct[u'instrument'] = None
            dct[u'label'] = str(device)
            dct[u'name'] = str(device)
            dct[u'ndim'] = 0
            dct[u'normalization'] = 0
            if flagOutput:
                dct[u'output'] = True
            else:
                dct[u'output'] = False
            dct[u'plot_axes'] = [u'<mov>']
            if flagDisplay:
                dct[u'plot_type'] = 1
            else:
                dct[u'plot_type'] = 0
            dct[u'source'] = dct['full_name'] + "/value"
            ctrlChannels[self.findFullDeviceName(device)] = dct
        return True

    def addSCAD9(self, device, flagDisplay, flagOutput):
        """
        add a SCA to the measurement group
          input: device, e.g. sca_exp_mca01_100_200
        """
        if device.find('sca_') != 0:
            print("MgUtils.addSCA: '%s' does not begin with 'sca_'," % device)
            return False

        #
        # there is one element per controller
        #
        fullCtrlName = self._addSca(device)
        if fullCtrlName not in self.hsh[u'controllers'].keys():
            print("MgUtils.addSca adding controller ", fullCtrlName)
            self.hsh[u'controllers'][fullCtrlName] = {}
            ctrl = fullCtrlName
            self.hsh[u'controllers'][ctrl][u'synchronizer'] = "software"
            self.hsh[u'controllers'][ctrl][u'channels'] = {}
            self.hsh[u'controllers'][ctrl][u'id'] = 0
            self.hsh[u'controllers'][ctrl][u'monitor'] = \
                self.findFullDeviceName(device)
            self.hsh[u'controllers'][ctrl][u'timer'] = \
                self.findFullDeviceName(device)
            self.hsh[u'controllers'][ctrl][u'trigger_type'] = 0

        ctrlChannels = self.hsh[u'controllers'][fullCtrlName][u'channels']
        if not self.findFullDeviceName(device) in ctrlChannels.keys():
            print("adding index", self.index, device)
            dct = {}
            dct[u'conditioning'] = u''
            dct[u'enabled'] = True
            dct[u'full_name'] = self.findFullDeviceName(device)
            dct[u'index'] = self.index
            self.index += 1
            dct[u'label'] = str(device)
            dct[u'name'] = str(device)
            dct[u'ndim'] = 0
            dct[u'normalization'] = 0
            if flagOutput:
                dct[u'output'] = True
            else:
                dct[u'output'] = False
            dct[u'plot_axes'] = [u'<mov>']
            if flagDisplay:
                dct[u'plot_type'] = 1
            else:
                dct[u'plot_type'] = 0
            dct[u'source'] = dct['full_name'] + "/value"
            ctrlChannels[self.findFullDeviceName(device)] = dct
        return True
Ejemplo n.º 9
0
class TangoDevice(object):
    """
    Wrapper for basic Tango device.
    It provides registering device, halting device and executing commands
    """
    POLL_STATE_TIME = 0.5
    TEST_MODE = False

    def __init__(self, devicePath=None):
        """
        Class constructor
        @type devicePath: String
        """
        self.devicePath = devicePath
        self.maxValue = False
        self.minValue = False
        self.name = "Generic device"
        self.output = {}
        self.profiling = False
        self.deviceError = False
        self.defaultClass = self.__class__

        # state change marker
        self._bstate_changed = False
        self.old_state = None

        self.__thread = None

        try:
            self.__device_init()
        except:
            logging.error(
                str("Device %s could not be connected" % self.devicePath))
            self.name = self.devicePath
            if config.DEVICE_ALLOW_RETRY:
                self._retry_device()
                #raise Exception(str("Device %s could not be connected" % self.devicePath))
                # logging.error(str("Device %s could not be connected" % self.devicePath))
                #else:

                #raise Exception(str("Device %s could not be connected" % self.devicePath))

    def __postInit__(self):
        pass

    def __device_init(self):
        self.device = DeviceProxy(self.devicePath)
        info = self.device.import_info()
        self.name = info.name

        if (self.name in DEVICE_NAMES):
            self.name = DEVICE_NAMES[self.name]

        self.deviceError = False
        self.__postInit__()

    def _retry_device(self, callback=None):
        self.deviceError = True
        thread = Thread(target=self.__retry_routine, args=([callback]))
        threads.add_thread(thread)
        thread.start()
        self.__class__ = DummyDevice

    def __retry_routine(self, callback):
        retrySleep = [True]
        while (retrySleep[0] and threads.THREAD_KEEP_ALIVE):
            try:
                DeviceProxy(self.devicePath).state()
                logging.error("Device online: %s" % (self.devicePath))
                retrySleep = [False]
            except:
                logging.error("Device offline, retrying: %s" %
                              (self.devicePath))
            threads.thread_sleep(config.DEVICE_RETRY_INTERVAL,
                                 sleepFlags=retrySleep)
        if threads.THREAD_KEEP_ALIVE == True:
            self.__class__ = self.defaultClass
            self.__device_init()
            if callback: callback()
        return True

    def isDeviceError(self):
        return self.deviceError

    def halt(self, callBack=None):
        """
        Stop device
        """
        pass

    def running_remove(self, *args):
        """
        Remove device from all running devices set
        """
        try:
            if (not stopDevices):
                runningDevices.remove(self)
        except:
            pass

    def running_add(self):
        """
        Add device to all runing devices set
        """
        global runningDevices
        runningDevices.add(self)

    def is_connected(self):
        """
        Return true if device is connected
        @rtype: bool
        """
        if self.device is None: return False
        else: return True

    def read_attributes(self, attributes):
        try:
            return self.device.read_attributes(attributes)
        except:
            logging.error("Device read attribute error: retrying device")
            if not config.DEVICE_ALLOW_RETRY:
                raise Exception(
                    str("Device %s could not be connected" % self.devicePath))
            else:
                self._retry_device()
                return self.read_attributes(attributes)

    def read_attribute(self, attribute):
        try:
            return self.device.read_attribute(attribute)
        except:
            if not config.DEVICE_ALLOW_RETRY:
                raise Exception(
                    str("Device %s could not be connected" % self.devicePath))
            else:
                self._retry_device()
                return self.read_attribute(attribute)

    def write_attributes(self, attributes):
        """
        Write attribute to device
        @type attributes: list
        @rtype: String
        """
        res = None
        if self.device:
            for attribute in attributes:
                logging.info("Attribute: %s wrote on device: %s", attribute[0],
                             self.devicePath)

            try:
                self.device.state()
                res = self.device.write_attributes(attributes)
            except (DevFailed, AttributeError) as e:
                pass
        return res

    def write_attributes_async(self, attributes, callback=None):
        res = None
        if self.device:
            for attribute in attributes:
                logging.info("Attribute: %s wrote on device: %s", attribute[0],
                             self.devicePath)

            try:
                self.device.state()
                res = self.device.write_attributes_asynch(attributes, callback)
            except (DevFailed, AttributeError) as e:
                pass
        return res

    def execute_command(self, commandName, commandParam=None):
        """
        Execute command on device
        @type commandName: String
        @type commandParam: String
        @rtype: String
        """
        try:
            if self.device:
                return self.device.command_inout(commandName, commandParam)
        except:
            if not config.DEVICE_ALLOW_RETRY:
                raise Exception(
                    str("Device %s could not be connected" % self.devicePath))
            else:
                self._retry_device()
                return self.execute_command(commandName, commandParam)

    def wait_for_state(self, state, callback=None):
        """
        Wait for state
        @type state: DevState.state
        """
        if self.device:
            while (self.device.state() == state):
                sleep(self.POLL_STATE_TIME)
            if not (callback is None): callback(self)

    def wait_seconds(self, duration=1):
        """
        Wait for a time duration
        @type duration: float if not config.DEVICE_ALLOW_RETRY: 
                raise Exception(str("Device %s could not be connected" % self.devicePath))
            else: 
                self._retry_device()
                return self.execute_command(commandName, commandParam)
        """
        if self.device:
            sleep(duration)

    def poll(self,
             commandName,
             duration=0.1,
             commandResult=True,
             callback=None,
             commandParam=None):
        """
        Poll device with command
        @type commandName: String
        @type duration: float
        @type callback: fun
        @type commandParam: String  
        """
        while (self.execute_command(commandName, commandParam) == commandResult
               and threads.THREAD_KEEP_ALIVE):
            self.wait_seconds(duration)
        if not (callback is None): callback(self)

    def poll_attribute(self,
                       attrName,
                       duration=0.1,
                       attributeResult=True,
                       callback=None,
                       commandParam=None):
        """
        Poll device with command
        @type attrName: String
        @type duration: float
        @type callback: fun
        @type commandParam: String
        """
        while (self.read_attribute(attrName).value == attributeResult
               and threads.THREAD_KEEP_ALIVE):
            self.wait_seconds(duration)
        if not (callback is None): callback(self)

    def check_idle(self):
        """
        Check if device id idle
        """
        pass

    def is_idle(self):
        """
        Return True if is idle, False if not and None if unknown 
        """
        return None

    def start_profiling(self):
        if self.profiling: return False
        self.profiling = True
        logging.info("Profiling of device %s started" % self.devicePath)
        return True

    def stop_profiling(self):
        self.profiling = False
        self.cleanup_thread()

    def current_value(self, value):
        return self.read_attribute(value).value

    def __profiling_routine(self):
        pass

    @property
    def thread(self):
        return self.__thread

    def start_external_profiling(self, func):
        """
        Starts profiling with an external function
        """
        self.profiling = True

        if self.__thread is None:
            thread = threads.threading.Thread(target=func, args=([self]))
            threads.add_thread(thread)
            thread.start()

            self.__thread = thread

    def cleanup_thread(self):
        if self.__thread is not None:
            self.profiling = False
            threads.join_thread(self.__thread)
            self.__thread = None

    def state(self):
        """
        Overload of the state function to keep track of old states
        :return:
        """
        state = None
        try:
            state = DeviceProxy(self.devicePath).state()

            self._bstate_changed = False
            if state != self.old_state:
                self.old_state = state
                self._bstate_changed = True
        except DevFailed:
            pass
        return state

    def is_state_changed(self):
        return self._bstate_changed
Ejemplo n.º 10
0
class TangoConnector(Connector):

    value_changed = pyqtSignal(str, name="valueChanged")

    def __init__(self,
                 uri=None,
                 attributes=[],
                 policy=UpdatePolicy.POLLING,
                 interval=1.0):
        #QThread.__init__(self)
        self.alive = False
        self.connected = False
        self.poll_attributes = {}
        self.thread = threading.Thread(target=self.run, name=uri)
        try:
            self.proxy = DeviceProxy(uri)
            self.connected = True
        except:
            self.attributes["state"]["value"] = State.UNKNOWN
            self.janus.utils["logger"].error("TangoConnector(" + self.uri +
                                             ").__init__() " +
                                             "connection failed")
            self.janus.utils["logger"].debug("", exc_info=True)
        Connector.__init__(self, uri, attributes, policy, interval)

    def add_attribute(self, attribute=None):
        Connector.add_attribute(self, attribute=attribute)
        if type(attribute) is not dict or "attr" not in attribute:
            return
        if "mode" in attribute and attribute["mode"] == "execute":
            return
        if "name" in attribute:
            name = attribute["name"]
        else:
            name = attribute["attr"].lower()
        self.poll_attributes[attribute["attr"]] = name

    def update_policy(self, policy=UpdatePolicy.POLLING, interval=1.0):
        self.interval = interval
        if policy != UpdatePolicy.POLLING and self.isRunning():
            self.stop()
        elif policy != UpdatePolicy.EVENTBASED:
            for attr in self.attributes.keys():
                if "event" not in self.attributes[attr]:
                    continue
                try:
                    self.proxy.unsubscribe_event(
                        self.attributes[attr]["event"])
                except:
                    self.janus.utils["logger"].error(
                        "TangoConnector(" + self.uri + ").update_policy() " +
                        "failed to unsubscribe from tango event")
                    self.janus.utils["logger"].debug("", exc_info=True)
                del self.attributes[attr]["event"]
        if policy == UpdatePolicy.POLLING and not self.thread.is_alive():
            self.thread.start()
        elif policy == UpdatePolicy.EVENTBASED:
            for attr in self.attributes.keys:
                try:
                    self.attributes[attr]["event"] = \
                        self.proxy.subscribe_event(EventType.CHANGE_EVENT, \
                                self.on_tango_event, [], False)
                except:
                    self.janus.utils["logger"].error(
                        "TangoConnector(" + self.uri + ").update_policy() " +
                        "failed to subscribe to tango event")
                    self.janus.utils["logger"].debug("", exc_info=True)
        self.policy = policy

    def on_tango_event(self, event):
        try:
            name = event.attr_name
            value = event.attr_value.value
        except:
            self.janus.utils["logger"].warning("TangoConnector(" + self.uri +
                                               ").on_tango_event() " +
                                               "invalid tango event type")
            self.janus.utils["logger"].debug("", exc_info=True)
        self.attributes[self.poll_attributes[name]]["value"] = value
        self.value_changed.emit(self.poll_attributes[name])

    def stop_device(self):
        self.stop()

    def stop(self):
        self.alive = False
        self.thread.join()
        pass

    def run(self):
        print("thread started: {} ({})".format(
            threading.get_ident(),
            threading.currentThread().getName()))
        self.alive = True
        while self.alive:
            #remember when we started
            timestamp = time.time()
            #try to poll attributes
            try:
                attrs = self.proxy.read_attributes(
                    list(self.poll_attributes.keys()))
            except:
                self.attributes["state"]["value"] = State.UNKNOWN
                self.janus.utils["logger"].error(
                    "TangoConnector(" + self.uri + ").run() " +
                    "reading tango attributes failed")
                self.janus.utils["logger"].debug("", exc_info=True)
                attrs = []
            #assign attribute values and fire change signal if necessary
            for attr in attrs:
                name = self.poll_attributes[attr.name]
                changed = False
                if "delta" in self.attributes[name]:
                    if self.attributes[name]["value"] is None or \
                            abs(self.attributes[name]["value"] - attr.value) > \
                            self.attributes[name]["delta"]:
                        changed = True
                elif name == "state" and \
                        int(self.attributes[name]["value"]) != int(attr.value):
                    changed = True
                elif name == "image_8":
                    changed = True
                elif self.attributes[name]["value"] != attr.value:
                    changed = True
                if changed:
                    if name == "state":
                        self.attributes[name]["value"] = State(int(attr.value))
                    else:
                        self.attributes[name]["value"] = attr.value
                    self.value_changed.emit(name)
                if not self.alive:
                    break
            #wait for the rest of the polling interval
            interval = int((self.interval - (time.time() - timestamp)))
            while interval > 0:
                if interval > 0.05:
                    time.sleep(0.05)
                    interval -= 0.05
                else:
                    time.sleep(interval)
                    interval = 0
                if not self.alive:
                    break
        print("closing thread: {} ({})".format(
            threading.get_ident(),
            threading.currentThread().getName()))

    def state(self, refresh=False):
        if refresh:
            try:
                self.attributes["state"]["value"] = State(
                    int(self.proxy.state()))
            except:
                self.attributes["state"]["value"] = State.UNKNOWN
                self.janus.utils["logger"].error("TangoConnector(" + self.uri +
                                                 ").state() " +
                                                 "reading tango state failed")
                self.janus.utils["logger"].debug("", exc_info=True)
        return self.attributes["state"]["value"]

    def read(self, attribute=None, refresh=False, alt=None):
        if refresh or self.attributes[attribute]["value"] is None:
            try:
                self.attributes[attribute]["value"] = \
                    self.proxy.read_attribute(self.attributes[attribute]["attr"]).value
            except:
                self.janus.utils["logger"].error(
                    "TangoConnector(" + self.uri + ")" + ".read(" + attribute +
                    ") " + "reading tango attribute failed")
                self.janus.utils["logger"].debug("", exc_info=True)
                if self.attributes[attribute]["value"] is None \
                        and alt is not None:
                    return alt
        return self.attributes[attribute]["value"]

    def write(self, attribute=None, value=None):
        try:
            self.proxy.write_attribute(self.attributes[attribute]["attr"],
                                       value)
            return True
        except:
            self.janus.utils["logger"].error("TangoConnector(" + self.uri +
                                             ")" + ".write(" + attribute +
                                             ") " +
                                             "writing tango attribute failed")
            self.janus.utils["logger"].debug("", exc_info=True)
            return False

    def execute(self, command=None, *values):
        try:
            if len(values) == 0:
                value = self.proxy.command_inout(
                    self.attributes[command]["attr"])
            else:
                value = self.proxy.command_inout(
                    self.attributes[command]["attr"], values)
        except Exception as e:
            self.janus.utils["logger"].error("TangoConnector(" + self.uri +
                                             ")" + ".execute(" + command +
                                             ") " +
                                             "executing tango command failed")
            self.janus.utils["logger"].debug("", exc_info=True)
            return None
        return value