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)
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
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()
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>')
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)
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]
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))
def gen_helpindex(self): ret = [ '<p class="menu">' '<a href="#commands">Commands</a> | ' '<a href="#devices">Devices</a> | ' '<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)
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