Package: nxsconfigserver
Welcome to NeXuS Configuration Server’s documentation!Authors: Jan Kotanski, Eugen Wintersberger, Halil PasicNeXuS Configuration Server is a Tango Server with its implementation based
on a MySQL database. It allows to store XML configuration datasources
and components. It also gives possibility to select mandatory components
and perform the process of component merging.Tango Server API:https://nexdatas.github.io/nxsconfigserver/doc_htmlSource code:https://github.com/nexdatas/nxsconfigserver/Web page:https://nexdatas.github.io/nxsconfigserver/NexDaTaS Web page:https://nexdatas.github.ioInstallationInstall the dependencies:MySQLdb, PyTango, sphinxFrom sourcesDownload the latest version of NeXuS Configuration Server fromhttps://github.com/nexdatas/nxsconfigserver/https://github.com/nexdatas/nxsconfigserver-db/Extract the sources and run$pythonsetup.pyinstallTo set database execute$mysql<conf/mysql_create.sqlwith proper privileges.Debian packagesDebian Bookworm, Bullseye, Buster and as well as Ubuntu Lunar, Jammy  packages can be found in the HDRI repository.To install the debian packages, add the PGP repository key$sudosu$wget-q-O-http://repos.pni-hdri.de/debian_repo.pub.gpg|apt-keyadd-and then download the corresponding source list, e.g. for bookworm$cd/etc/apt/sources.list.d$wgethttp://repos.pni-hdri.de/bookworm-pni-hdri.listFinally, for python2 packages$apt-getupdate$apt-getinstallpython-nxsconfigservernxsconfigserver-dband the NXSConfigServer tango server (from 2.10.0)$ apt-get install nxsconfigserveror for python3$apt-getupdate$apt-getinstallpython3-nxsconfigservernxsconfigserver-dband the NXSConfigServer tango server (from 2.10.0)$ apt-get install nxsconfigserver3From pipTo install it from pip you need pymysqldb e.g.$python3-mvenvmyvenv$.myvenv/bin/activate$pipinstallpymysqldb$pipinstallnxsconfigserverMoreover it is also good to install$pipinstallpytango$pipinstallnxstoolsSetting NeXus Configuration ServerTo set up  NeXus Configuration Server with the default configuration run$nxsetup-xNXSConfigServerThenxsetupcommand comes from thepython-nxstoolspackage.DescriptionConfiguration Server is dedicated to store NXDL-like configuration needed for
Tango Data Writer runs. The server uses as a storage system a MYSQL database.
To create required DB tables one can use ndts.sql script from the repository.In Configuration Server the configuration is memorized in separate elements:
datasources or components.DataSourcesdescribe access to input data, i.e to specific hardware
TANGO devices or other databases as well to client data.Componentsspecify Nexus tree with positions of datasets for particular
pieces of hardware and writing strategy for corresponding to them data.They can include datasources directly as well as links to datasources
defined in the server. To this end template syntax of
$datasources.<ds_name> type is used.Moreover, they can holds links to other components which describe their
dependences. In this case $components.<comp_name> syntax is used.Finally, the components can contains variables. The variables are defined
in XML code by $var.<var_name> syntax and can be provided to
the Configuration Server by passing a JSON string.
The default value for variables is an empty string.All elements of configuration can be created by GUI tool - ComponentDesigner.
The tool can connect to Configuration Server and fetch or store
the separate elements of the XML configuration.During creation of the final configuration Configuration Server merges
all required and dependent components, connected to them datasources and
provided values of the variables. As a result it returns a single XML string.
This XML string can be pass directly into the dedicated Tango Data Writer
attribute.Client code# In this section we present an example how to communicate with# Configuration Server making use of PyTango.importtangocnfServer=tango.DeviceProxy("p00/xmlconfigserver/exp.01")cnfServer.JSONSettings=\'{"db":"ndts_p02","read_default_file":"/etc/my.cnf","use_unicode":true}'# opens DB connectioncnfServer.Open()# After creating the server proxy we can set configuration for connection to#  the MYSQL DB.# The JSONSettings attribute is memorized so you have to write it only when you# change configuration of DB connection. Next, we open connection to# DB specified by our JSONSettings.# stores default componentcpxml=open("default.xml",'r').read()cnfServer.XMLString=cpxmlcnfServer.StoreComponent('default')# stores slit1 component in DBcpxml=open("slit1.xml",'r').read()cnfServer.XMLString=cpxmlcnfServer.StoreComponent('slit1')# stores slit2 component in DBcpxml=open("slit2.xml",'r').read()cnfServer.XMLString=cpxmlcnfServer.StoreComponent('slit2')# stores slit3 component in DBcpxml=open("slit3.xml",'r').read()cnfServer.XMLString=cpxmlcnfServer.StoreComponent('slit3')# stores pilatus300k component in DBcpxml=open("pilatus.xml",'r').read()cnfServer.XMLString=cpxmlcnfServer.StoreComponent('pilatus300k')# stores motor01 datasource in DBdsxml=open("motor.ds.xml",'r').read()cnfServer.XMLString=dsxmlcnfServer.StoreDataSource('motor01')# stores motor02 datasource in DBdsxml=open("motor.ds.xml",'r').read()cnfServer.XMLString=dsxmlcnfServer.StoreDataSource('motor02')# removes slit3 component from DBcnfServer.DeleteComponent('slit3')# removes motor02 datasource from DBcnfServer.DeleteDataSource('motor02')# If someone cannot use ComponentDesigner it is also an option to store# or delete components and datasources using directly tango interface# as it is shown above.# provides names of available componentscmpNameList=cnfServer.AvailableComponents()# provides names of available datasourcesdsNameList=cnfServer.AvailableDataSources()# To get information about names of available components and datasources# in Configuration Server we use the above commands.# provides a list of required componentscmpList=cnfServer.Components(cmpNameList)# provides a list of required DatasourcesdsList=cnfServer.DataSources(dsNameList)# Having names of stored elements we can get their XML code.# provides a list of Datasources from a given ComponentdsList=cnf.Server.ComponentDataSources('pilatus300k')dsList=cnf.Server.ComponentsDataSources(['pilatus300k','slit1'])# as well as query Configuration Server which datasource# are related to the particular component.# provides a dependent componentscpList=cnf.Server.DependentComponents(['pilatus300k','slit3'])# Moreover, one can also query Configuration Server for a list of# dependent components# provides a list of Variables from a given componentsvarList=cnf.Server.ComponentVariables('pilatus300k')varList=cnf.Server.ComponentsVariables(['pilatus300k','slit3'])#or ask for a list of variables which are related to the particular components.# sets values of variablescnf.Server.Variables='{"entry_id":"123","beamtime_id":"123453535453"}'#The variable values can be passed to the Configuration Server# via a JSON string.# sets given component as mandatory for the final configurationcnfServer.SetMandatoryComponents(['default','slit1'])# un-sets given component as mandatory for the final configurationcnfServer.UnsetMandatoryComponents(['slit1'])# provides names of mandatory componentsman=cnfServer.MandatoryComponents()# Some of the component can be set as mandatory in# the final configuration. To define them Configuration Server provides# above commands.# provides the current configuration versionversion=cnfServer.Version# Each configuration has a revision number. It can be found# together with Configuration Server version in Version attribute.# creates the final configuration from slit2 and pilatus300k# as well as all mandatory componentscnfServer.CreateConfiguration('slit2','pilatus300k')# XML string ready to use by Tango Data ServerfinalXML=cnfServer.XMLString# In order to create our final configuration we execute CreateConfiguration# command with a list of names of required components. The command merges# these components with mandatory ones and provides the resulting NXDL-like# configuration in the XMLString attribute.# merges given componentsmergedComp=cnfServer.Merge(['slit2','pilatus300k'])# Similarly, the Merge command provides configuration by unresolved links# to datasoures and with non-assigned variable values.# closes connection to DBcnfServer.close()# Command close terminates our connection to the DB server.Configuration VariablesValues of configuration variables can be also define inside the component xmls.
Let’s consider two following components:mydetectorwith a general detector transformation group<definition><grouptype='NXentry'name='entry'><grouptype='NXinstrument'name='instrument'><grouptype='NXdetector'name='$var.detector#\"mydetector\"'><grouptype='NXtransformations'name='transformations'/></group></group></group></definition>andpilatuscreated for the particular detector<definition><grouptype='NXentry'name='entry'><grouptype='NXinstrument'name='instrument'><grouptype='NXdetector'name='pilatus'><fieldtype='NX_FLOAT64'name='data'/></group></group></group><doc>$var(detector=pilatus)</doc></definition>Creating configuration without variablescnfServer.Variables='{}'cnfServer.CreateConfiguration(["mydetector"])results in<definition><grouptype='NXentry'name='entry'><grouptype='NXinstrument'name='instrument'><grouptype='NXdetector'name='mydetector'><grouptype='NXtransformations'name='transformations'/></group></group></group></definition>When configuration variables are definedcnfServer.Variables='{"detector": "det1"}'cnfServer.CreateConfiguration(["mydetector"])one can get<definition><grouptype='NXentry'name='entry'><grouptype='NXinstrument'name='instrument'><grouptype='NXdetector'name='det1'><grouptype='NXtransformations'name='transformations'/></group></group></group></definition>Finally, creating configuration xml from our two components without variablescnfServer.Variables='{}'cnfServer.CreateConfiguration(["mydetector","pilatus"])results in<definition><groupname="entry"type="NXentry"><groupname="instrument"type="NXinstrument"><groupname="pilatus"type="NXdetector"><groupname="transformations"type="NXtransformations"/><fieldname="data"type="NX_FLOAT64"/></group></group></group><doc>$var(detector=pilatus)</doc></definition>