Example #1
0
def ListSetups(listall=False):
    """Print a list of setups.

    Example:

    >>> ListSetups()

    To list also low-level and simulation setups:

    >>> ListSetups(True)

    see also: `NewSetup`, `AddSetup`, `RemoveSetup`
    """
    session.log.info('Available setups:')
    items = []
    for name, info in iteritems(session.getSetupInfo()):
        if info is None:
            items.append((name, '', '<could not be read, check syntax>', ''))
            continue
        if info['group'] in ('special', 'configdata'):
            continue
        if info['group'] == 'lowlevel' and not listall:
            continue
        items.append((name, name in session.loaded_setups and 'yes' or '',
                      info['description'],
                      ', '.join(sorted(info['devices']))))
    items.sort()
    printTable(('name', 'loaded', 'description', 'devices'), items, session.log.info)
Example #2
0
 def getTableDevices(self):
     result = list(
         itertools.chain(self.standard_devices, self.additional_devices))
     setupInfo = session.getSetupInfo()
     for setup in self.setups:
         info = setupInfo[setup]
         result = list(itertools.chain(result, info['devices'].keys()))
     return result
Example #3
0
def refreshDeviceList(listall=True):
    listSetups = ['andes', 'astor', 'system']
    for name, info in session.getSetupInfo().items():
        if info is None:
            continue
        if info['group'] in ('special', 'configdata'):
            continue
        if info['group'] == 'lowlevel' and not listall:
            continue
        if name in session.loaded_setups and name not in listSetups:
            for dname in info['devices']:
                session.getDevice(dname).poll()
Example #4
0
 def listsetups(group):
     setups = []
     for setupname, info in sorted(iteritems(session.getSetupInfo())):
         if info is None or info['group'] != group:
             continue
         setups.append(
             '<tr><td><tt>%s</tt></td><td>%s</td>'
             '<td>%s</td><td>%s</td></tr>' %
             (setupname, setupname in session.loaded_setups and 'yes'
              or '', escape_html(info['description']), ', '.join(
                  map(devlink, sorted(info['devices'], key=lower)))))
     ret.append('<table width="100%"><tr><th>Name</th><th>Loaded</th>'
                '<th>Description</th><th>Devices</th></tr>')
     ret.extend(setups)
     ret.append('</table>')
Example #5
0
    def start(self, setup=None):
        self._setup = setup
        if setup is None:
            return self._start_master()
        self.log.info('%s poller starting', setup)

        if setup == '[dummy]':
            return

        try:
            session.loadSetup(setup, allow_startupcode=False)
            for devname in session.getSetupInfo()[setup]['devices']:
                if devname in self.blacklist:
                    self.log.debug('not polling %s, it is blacklisted',
                                   devname)
                    continue
                # import the device class in the main thread; this is necessary
                # for some external modules like Epics
                self.log.debug('importing device class for %s', devname)
                try:
                    session.importDevice(devname)
                except Exception:
                    self.log.warning(
                        '%-10s: error importing device class, '
                        'not retrying this device',
                        devname,
                        exc=True)
                    continue
                self.log.debug('starting thread for %s', devname)
                queue = Queue.Queue()
                worker = createThread('%s poller' % devname,
                                      self._worker_thread,
                                      args=(devname, queue))
                worker.queue = queue
                self._workers[devname.lower()] = worker
                # start staggered to not poll all devs at once....
                # use just a small delay, exact value does not matter
                sleep(0.0719)
            session.cache.addPrefixCallback('poller', self.enqueue_params_poll)

        except ConfigurationError as err:
            self.log.warning('Setup %r has failed to load!', setup)
            self.log.error(err, exc=True)
            self.log.warning('Not polling any devices!')

        # start a thread checking for modification of the setup file
        createThread('refresh checker', self._checker, args=(setup, ))
        self.log.info('%s poller startup complete', setup)
Example #6
0
 def _resolve_block(self, block):
     # exchange SetupBlock objects by their definition, or raise
     # a ConfigurationError if it doesn't exist.
     if not isinstance(block, SetupBlock):
         return block
     setup, bname = block._setupname, block._blockname
     setupinfo = session.getSetupInfo()
     if setup not in setupinfo:
         raise ConfigurationError(
             self, 'Setup "%s" required by '
             'SetupBlock() does not exist' % setup)
     blocks = setupinfo[setup]['monitor_blocks']
     if bname not in blocks:
         raise ConfigurationError(
             self, 'Setup "%s" does not define a  '
             'monitor block called "%s"' % (setup, bname))
     return blocks[bname]
Example #7
0
    def makeDynamicDevices(self, setup_info):
        """create and destroy dynamic devices

        create devices from setup_info, and store the name of the setup
        creating the creator device in session.creator_devices for
        session.getSetupInfo()
        Based on the previous setup_info from self.setup_info,
        devices are created, recreated, destroyed or remain unchanged.
        If setup_info is empty, destroy all devices.
        """
        prevdevices = set(self.setup_info.keys())
        self._setROParam('setup_info', setup_info)

        # find setup of this secnode
        result = session.getSetupInfo()
        for setupname in session.loaded_setups:
            info = result.get(setupname, None)
            if info and self.name in info['devices']:
                break
        else:
            raise ConfigurationError('can not find setup')
        # add new or changed devices
        for devname, devcfg in setup_info.items():
            prevdevices.discard(devname)
            dev = session.devices.get(devname, None)
            if dev:
                if not isinstance(dev, SecopDevice) or (dev._attached_secnode and
                                                        dev._attached_secnode != self):
                    self.log.error('device %s already exists' % devname)
                    continue
                base = dev.__class__.__bases__[0]
                prevcfg = base.__module__ + '.' + base.__name__, dict(secnode=self.name, **dev._config)
            else:
                prevcfg = None
            if prevcfg != devcfg:
                session.configured_devices[devname] = devcfg
                session.dynamic_devices[devname] = setupname  # pylint: disable=undefined-loop-variable
                if dev is None:
                    # add new device
                    session.createDevice(devname, recreate=True, explicit=True)
                    dev = session.devices[devname]
                else:
                    # modify existing device
                    if dev._attached_secnode:
                        dev._attached_secnode.unregisterDevice(dev)
                    session.configured_devices[devname] = devcfg
                    session.dynamic_devices[devname] = setupname  # pylint: disable=undefined-loop-variable
                    try:
                        dev.replaceClass(devcfg[1])
                        dev.setAlive(self)
                    except ConfigurationError:
                        # above failed because an alias or attaching device requires a specific class
                        # make old device defunct and replace by a new device
                        session.destroyDevice(dev)
                        session.dynamic_devices.pop(devname, None)
                        session.createDevice(devname, recreate=True, explicit=True)
                        prevdevices.discard(devname)
                        dev = session.devices[devname]
                if not isinstance(dev, SecopReadable):
                    # we will not get status updates for these
                    dev.updateSecopStatus((SecopStatus.IDLE, ''))

        defunct = set()
        # defunct devices no longer available
        for devname in prevdevices:
            dev = session.devices.get(devname)
            if dev is None or dev._attached_secnode != self:
                continue
            if dev._sdevs:
                self.log.warning('defunct device is attached to %s' % ', '.join(dev._sdevs))
            dev.setDefunct()
            defunct.add(devname)

        # inform client that setups have changed
        session.setupCallback(list(session.loaded_setups), list(session.explicit_setups))
Example #8
0
    def gen_helpindex(self):
        ret = [
            '<p class="menu">'
            '<a href="#commands">Commands</a>&nbsp;&nbsp;|&nbsp;&nbsp;'
            '<a href="#devices">Devices</a>&nbsp;&nbsp;|&nbsp;&nbsp;'
            '<a href="#setups">Setups</a></p>'
        ]
        ret.append('<p>Welcome to the NICOS interactive help!</p>')
        cmds = []
        for name, obj in session.getExportedObjects():
            if not hasattr(obj, 'is_usercommand'):
                continue
            real_func = getattr(obj, 'real_func', obj)
            if real_func.__name__.startswith('_'):
                continue
            if getattr(real_func, 'is_hidden', False):
                continue
            if real_func.__name__ != name:
                # it's an alias, don't show it again
                continue
            if hasattr(real_func, 'help_arglist'):
                argspec = '(%s)' % real_func.help_arglist
            else:
                argspec = formatArgs(real_func)
            signature = '<tt><a href="cmd:%s">%s</a></tt><small>' % \
                ((real_func.__name__,)*2) + escape_html(argspec) + '</small>'
            docstring = escape_html(real_func.__doc__ or ' ').splitlines()[0]
            cmds.append('<tr><td>%s</td><td>%s</td></tr>' %
                        (signature, docstring))
        cmds.sort()
        ret.append(self.gen_heading('NICOS commands', 'commands'))
        ret.append('<p>These commands are currently available.</p>')
        ret.append('<table width="100%">'
                   '<tr><th>Name</th><th>Short description</th></tr>')
        ret.extend(cmds)
        ret.append('</table>')
        ret.append(self.gen_heading('Devices', 'devices'))
        ret.append(
            '<p>These are the currently loaded high-level devices.  Use '
            '<a href="cmd:AddSetup">AddSetup()</a> or the "Setup" '
            'window to add more devices.</p>')
        ret.append('<table width="100%"><tr><th>Name</th><th>Type</th>'
                   '<th>From setup</th><th>Description</th></tr>')
        setupinfo = session.getSetupInfo()
        devsetups = {}
        for sname, info in iteritems(setupinfo):
            if info is None:
                continue
            for devname in info['devices']:
                devsetups[devname] = sname
        for devname in sorted(session.explicit_devices, key=lower):
            dev = session.devices[devname]
            ret.append(
                '<tr><td><tt><a href="dev:%s">%s</a></tt></td>'
                '<td>%s</td><td>%s</td><td>%s</td>' %
                (dev, dev, dev.__class__.__name__, devsetups.get(
                    devname, ''), escape_html(dev.description)))
        ret.append('</table>')
        ret.append(self.gen_heading('Setups', 'setups'))
        ret.append('<p>These are the available setups.  Use '
                   '<a href="cmd:AddSetup">AddSetup()</a> to load an '
                   'additional setup or <a href="cmd:NewSetup">NewSetup()</a>'
                   ' to load one or more completely new ones.</p>')

        def devlink(devname):
            if devname in session.devices:
                return '<a href="dev:%s">%s</a>' % (escape_html(devname),
                                                    escape_html(devname))
            return escape_html(devname)

        def listsetups(group):
            setups = []
            for setupname, info in sorted(iteritems(session.getSetupInfo())):
                if info is None or info['group'] != group:
                    continue
                setups.append(
                    '<tr><td><tt>%s</tt></td><td>%s</td>'
                    '<td>%s</td><td>%s</td></tr>' %
                    (setupname, setupname in session.loaded_setups and 'yes'
                     or '', escape_html(info['description']), ', '.join(
                         map(devlink, sorted(info['devices'], key=lower)))))
            ret.append('<table width="100%"><tr><th>Name</th><th>Loaded</th>'
                       '<th>Description</th><th>Devices</th></tr>')
            ret.extend(setups)
            ret.append('</table>')

        ret.append('<h4>Basic instrument setups</h4>')
        listsetups('basic')
        ret.append('<h4>Optional setups</h4>')
        listsetups('optional')
        ret.append('<h4>Plug-and-play setups</h4>')
        listsetups('plugplay')
        return ''.join(ret)
Example #9
0
    def _getMetadata(self):

        retval = ''

        devlist = [
            devname for devname in session.explicit_devices
            if isinstance(session.devices[devname], Readable)
        ]

        self.log.debug('devlist : %s', devlist)

        setups = session.getSetupInfo()
        setups_log = {}

        self.log.debug('setup list: %s', list(setups.keys()))

        for s in setups:
            self.log.debug('setup "%s":', s)
            s_devlist = (setups[s])['devices']
            self.log.debug(s_devlist)
            s_devlist = [d for d in s_devlist if d in devlist]
            self.log.debug(s_devlist)
            for d in s_devlist:
                if s not in setups_log.keys():
                    setups_log[s] = []
                setups_log[s].append(session.devices[d])

        self.log.debug(str(setups_log))

        for s in setups_log:
            for dev in setups_log[s]:

                # The FITS standard defines max 8 characters for a header key.
                # To make longer keys possible, we use the HIERARCH keyword
                # here (67 chars max).
                # To get a consistent looking header, add it to every key
                key = 'HIERARCH ' + s + '/' + dev.name

                # use only ascii characters and escapes if necessary.
                try:
                    val = dev.read(0)
                    value = dev.format(val, unit=True).encode('unicode-escape')
                except Exception as e:
                    session.log.warning(
                        'Failed to read dev.name, %s,'
                        ' with %s', dev.name, e)
                    session.log.warning('Offending value: %s', val)
                    value = 'Unknown'

                # Determine maximum possible value length (key dependend).
                maxValLen = 63 - len(key)

                # Split the dataset into several header entries if necessary
                # (due to the limited length)
                splittedHeaderItems = [
                    value[i:i + maxValLen]
                    for i in range(0, len(value), maxValLen)
                ]

                for item in splittedHeaderItems:
                    retval = retval + (key + ' = ' + str(item)).ljust(80)[:80]

        return retval