#!/usr/Local/pyroot/PyTangoRoot/bin/python """ Python module for scanning and saving configuration of devices. Includes a Command Line Interface. Can be imported as is to use function in user script. """ import PyTango as tango import logging import argparse import json import numpy __version__ = "1.0.0" ##---------------------------------------------------------------------------## def get_wattr(proxy): """ Get all writable attributes from a device and save their values in a python dict. Parameters ---------- proxy : PyTango.DeviceProxy Proxy to the device. Returns ------- config : dict Dictionnary, keys are attribute names and value their present values. """ logger.debug("Scanning write attribute of device %s"%proxy.name()) config = dict() # Get all attributes configuration cattr = proxy.get_attribute_config(proxy.get_attribute_list()) wattr=[] for attr in cattr: logger.debug("Analyse attribute '%s' "%( attr.name)) if attr.writable in [ tango.AttrWriteType.WRITE, tango.AttrWriteType.READ_WRITE, tango.AttrWriteType.READ_WITH_WRITE]: # attr is writtable, savbing it into list wattr.append(attr.name) logger.debug("Detect writtable attribute '%s'"%( attr.name)) # Read all writtable attributes rattr = proxy.read_attributes(wattr) for attr in rattr: v= attr.value if type(v) is numpy.ndarray: v=v.tolist() logger.debug("Read writtable attribute '%s' = %s"%( attr.name, v)) config[attr.name]=v return config ##---------------------------------------------------------------------------## def get_properties(proxy): """ Get all properties from a device and save them in a python dict. Parameters ---------- proxy : PyTango.DeviceProxy Proxy to the device. Returns ------- config : dict Dictionnary, keys are attribute names and value their present values. """ logger.debug("Scanning properties of device %s"%proxy.name()) pl = proxy.get_property_list('*') _props = proxy.get_property(pl) props=dict() # Here we simply convert tango arrays to python arrays. # For properties, each prop is an array, one element in # the array is a line for the property. # Maybe we need to convert in one single string. for k in _props.keys(): if k[:2] !="__": # Change type props[k] = list(_props[k]) logger.debug("Detect property %s = %s"%( k, props[k])) return props ########################################################################## """ Command Line Interface """ if __name__ == "__main__": # Name the logger after the filename logger = logging.getLogger("ContextSaver") ####################################################### # Install argument parser import argparse parser = argparse.ArgumentParser(description="Copy attributes and properties to a JSON structure.\n"+ "Version %s"%__version__) parser.add_argument("--fileout", type=str, help="Save the JSON structure to the specified file. Implicit set no output to stdout."), parser.add_argument('--log', type=str, default="INFO", help="Log level. Default: %(default)s.") parser.add_argument('-v', action="store_true", help="Print in stdout the context. Default is on if no fileout option specified.") parser.add_argument('--filemode', action="store_true", help="Set devices to filemode."+ " Instead of specifying devices, put a path to a file containing a list of devices."+ " The file contains one device path per line.") parser.add_argument('devices', type=str, nargs='+', help="List of devices to inspect. Full tango path.") args = parser.parse_args() ####################################################### # Configure logger # Add a stream handler s_handler = logging.StreamHandler() s_handler.setFormatter(logging.Formatter("%(levelname)s\t[%(funcName)s] \t%(message)s")) # Set level according to command line attribute s_handler.setLevel(level=getattr(logging, args.log.upper())) logger.setLevel(level=getattr(logging, args.log.upper())) logger.addHandler(s_handler) logger.debug("Parsed arguments: %s"%args) logger.info("Context Saver %s"%__version__) ####################################################### # Filemode or not if args.filemode: logger.info("Filemode, openning file %s"%args.devices[0]) # Read the file. Each line is an device with open(args.devices[0], "r") as fp: devices = fp.readlines() logger.debug("Read lines : %s"%devices) # Clean end of line for i_a in range(len(devices)): devices[i_a] = devices[i_a].rstrip() else: devices = args.devices ####################################################### # Prepare array for result results = dict() ####################################################### # Scan all devices for dev in devices: logger.info("Scanning device %s..."%dev) # Declare proxy prx = tango.DeviceProxy(dev) # Retrieve write attributes wattr = get_wattr(prx) # Retrieve properties props = get_properties(prx) # Build json dict jdict = { "wattributes":wattr, "properties":props, } # Add to results results[dev] = jdict logger.info("Done") if args.fileout is None: print(json.dumps(results, indent=4)) else: with open(args.fileout, "w") as fp: json.dump(results, fp, indent=4) # Additionnal dump to stdout if args.v: print(json.dumps(results, indent=4)) else: # Name the logger after the module name logger = logging.getLogger(__name__)