This is an old revision of the document!
Installer une version recente de mongodb sur MONPC
Pour la base 'cool_db
'
use cool_db
db.createUser({ user: 'ian', pwd: 'secretPassword', roles: [{ role: 'readWrite', db:'cool_db'}] })
Puis on modifie /etc/mongod.conf
# network interfaces net: port: 27017 bindIp: 0.0.0.0
security: authorization: 'enabled'
On peut ainsi acceder a la base cool_db a distance
mongo -u ian -p secretPassword MONPC/cool_db
La creation des table dans la base de donnees se fait par insertion d'objets dans les tables
Pour creer la base elle meme, il suffit de se connecter avec mongo
et de taper:
use MaBase
pour creer la base MaBase
Les tables sont creees par insertion par le script python
Du cote client, seul l'acces au base mongodb est necessaire a travers des scripts python. Sur les distributions basees sur debian il suffit d'installer
le paquet python-pymongo
sudo apt-get install python-pymongo
Un state est un nom une version et une liste d'asic. En cas de modification d'un parametre, une nouvelle entree des asics modifies est faite. La liste et le numero de version sont aussi aussi modifies
Chaque ASIC est identifie par son numero de DIF et son numero d'ASIC, un tag address
peut egalement etre utilise. Les valeurs de chargement du slow control
sont enumerees sou le tag slc
. Elles correspondent aux parametres decrits dans les documentations des deux chips.
Le numero de DIF correspond a l'adresse IP:
3594 = 0xe0a ⇒ 15.10 et l'adresse IP est 192.168.10.15
{"dif": 3594, "num": 1, "slc": {"6bDac": [1, 1, 1, 1, 30, 28, 31, 30, 30, 25, 30, 38, 39, 30, 33, 41, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "Cf0_1p25pF": 0, "Cf1_2p5pF": 0, "Cf2_200fF": 0, "Cf3_100fF": 0, "Choice_Trigger_Out": 0, "DIS_razchn_ext": 0, "DIS_razchn_int": 1, "DIS_trig_mux": 1, "DIS_triggers": 0, "DacDelay": 31, "EN10bDac": 1, "EN_80M": 0, "EN_NOR32_charge": 0, "EN_NOR32_time": 1, "EN_adc": 0, "EN_bias_6bit_dac": 1, "EN_bias_charge": 0, "EN_bias_dac_delay": 0, "EN_bias_discri": 1, "EN_bias_discri_adc_charge": 0, "EN_bias_discri_adc_time": 0, "EN_bias_discri_charge": 0, "EN_bias_pa": 1, "EN_bias_ramp_delay": 0, "EN_bias_sca": 0, "EN_bias_tdc": 0, "EN_discri_delay": 0, "EN_dout_oc": 0, "EN_fast_lvds_rec": 1, "EN_slow_lvds_rec": 1, "EN_temp_sensor": 0, "EN_transmit": 0, "EN_transmitter": 0, "InputDac": [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], "InputDacCommand": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "MaskDiscriCharge": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "MaskDiscriTime": [1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "ON_OFF_1mA": 1, "ON_OFF_2mA": 1, "ON_OFF_input_dac": 1, "ON_OFF_otaQ": 0, "ON_OFF_ota_mux": 0, "ON_OFF_ota_probe": 0, "PA_ccomp_0": 1, "PA_ccomp_1": 1, "PA_ccomp_2": 1, "PA_ccomp_3": 1, "PP10bDac": 0, "PP_adc": 0, "PP_bias_6bit_dac": 0, "PP_bias_charge": 0, "PP_bias_dac_delay": 0, "PP_bias_discri": 0, "PP_bias_discri_adc_charge": 0, "PP_bias_discri_adc_time": 0, "PP_bias_discri_charge": 0, "PP_bias_pa": 0, "PP_bias_ramp_delay": 0, "PP_bias_sca": 0, "PP_bias_tdc": 0, "PP_discri_delay": 0, "PP_fast_lvds_rec": 0, "PP_slow_lvds_rec": 0, "PP_temp_sensor": 0, "PP_transmitter": 0, "SEL_80M": 0, "VthDiscriCharge": 863, "VthTime": 515, "cmd_polarity": 0, "header": 1, "latch": 1, "sel_starb_ramp_adc_ext": 0, "usebcompensation": 0}}
Cette fois ci l'adresse IP est specifiee, 4708=0x1264 =⇒ 18.100
{"address": "192.168.100.18", "dif": 4708, "num": 1, "slc": { "B0": 145, "B1": 250, "B2": 250, "CLKMUX": 1, "CMDB0FSB1": 1, "CMDB0FSB2": 1, "CMDB0SS": 0, "CMDB1FSB1": 1, "CMDB1FSB2": 1, "CMDB1SS": 0, "CMDB2FSB1": 0, "CMDB2FSB2": 0, "CMDB2SS": 0, "CMDB3FSB1": 1, "CMDB3FSB2": 1, "CMDB3SS": 0, "CTEST": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "DACSW": 1, "DISCRI0": 1, "DISCRI1": 1, "DISCRI2": 1, "DISCROROR": 1, "ENOCCHIPSATB": 1, "ENOCDOUT1B": 1, "ENOCDOUT2B": 0, "ENOCTRANSMITON1B": 1, "ENOCTRANSMITON2B": 0, "ENTRIGOUT": 1, "EN_OTAQ": 1, "HEADER": 1, "MASK0": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "MASK1": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "MASK2": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "OTABGSW": 1, "OTAQ_PWRADC": 1, "PAGAIN": [128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128], "PWRONBUFF": 1, "PWRONFSB0": 1, "PWRONFSB1": 1, "PWRONFSB2": 1, "PWRONPA": 1, "PWRONSS": 0, "PWRONW": 1, "QSCSROUTSC": 1, "RAZCHNEXTVAL": 0, "RAZCHNINTVAL": 1, "RS_OR_DISCRI": 1, "SCON": 1, "SEL0": 1, "SEL1": 0, "SELENDREADOUT": 1, "SELSTARTREADOUT": 1, "SMALLDAC": 0, "SW100F0": 1, "SW100F1": 1, "SW100F2": 1, "SW100K0": 1, "SW100K1": 1, "SW100K2": 1, "SW50F0": 1, "SW50F1": 1, "SW50F2": 1, "SW50K0": 1, "SW50K1": 1, "SW50K2": 1, "SWSSC": 7, "TRIG0B": 1, "TRIG1B": 0, "TRIG2B": 0, "TRIGEXTVAL": 0}}
Un tag address
est defini pour avoir une approche unifiee: 0.0.0.#dif
{ "address": "0.0.0.5", "dif": 5, "num": 1, "slc": {"B0": 170, "B1": 250, "B2": 250, "CLKMUX": 1, "CMDB0FSB1": 1, "CMDB0FSB2": 1, "CMDB0SS": 0, "CMDB1FSB1": 1, "CMDB1FSB2": 1, "CMDB1SS": 0, "CMDB2FSB1": 0, "CMDB2FSB2": 0, "CMDB2SS": 0, "CMDB3FSB1": 1, "CMDB3FSB2": 1, "CMDB3SS": 0, "CTEST": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], "DACSW": 1, "DISCRI0": 1, "DISCRI1": 1, "DISCRI2": 1, "DISCROROR": 1, "ENABLED": 1, "ENOCCHIPSATB": 1, "ENOCDOUT1B": 1, "ENOCDOUT2B": 0, "ENOCTRANSMITON1B": 1, "ENOCTRANSMITON2B": 0, "ENTRIGOUT": 1, "EN_OTAQ": 1, "HEADER": 1, "MASK0": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "MASK1": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "MASK2": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], "OTABGSW": 1, "OTAQ_PWRADC": 1, "PAGAIN": [128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128], "PWRONBUFF": 1, "PWRONFSB0": 1, "PWRONFSB1": 1, "PWRONFSB2": 1, "PWRONPA": 1, "PWRONSS": 0, "PWRONW": 1, "QSCSROUTSC": 1, "RAZCHNEXTVAL": 0, "RAZCHNINTVAL": 1, "RS_OR_DISCRI": 1, "SCON": 1, "SEL0": 1, "SEL1": 0, "SELENDREADOUT": 1, "SELSTARTREADOUT": 1, "SMALLDAC": 0, "SW100F0": 1, "SW100F1": 1, "SW100F2": 1, "SW100K0": 1, "SW100K1": 1, "SW100K2": 1, "SW50F0": 1, "SW50F1": 1, "SW50F2": 1, "SW50K0": 1, "SW50K1": 1, "SW50K2": 1, "SWSSC": 7, "TRIG0B": 1, "TRIG1B": 0, "TRIG2B": 0, "TRIGEXTVAL": 0}}
L'objet MongoRoc offre l'access a la base mongo ou les configurations d'ASICs sont stockees
On cree une instance de l'objet avec la method instance()
, pour cela il faut avoir defini la variable d'environnment MGDBLOGIN sous la forme:
MGDBLOGIN=userXXX/pwdXXX@hostYYY:27017@MYDB ou userXXX est le usernamce pwdXXX est le password hostYYY est le pc sur lequel la base est installle 27017 est le port d'acces MYDB est le nom de la base
On peut etablir un tunnel ssh pour acceder une base distante
ssh -fN -L 27037:hostYYY:27017 user@proxy
Dans ce cas on aura
MGDBLOGIN=userXXX/pwdXXX@localhost:27037@MYDB
Le script mgroc permet d'enumerer les etats de la base disponibles et de telecharger un etat donne dans /dev/shm/mgroc/statename_version.json
mgroc --states ... CERN2B_1415 1 upload from oracle FEB_2B_1415_16 DIF_ALGECO 1 Un essai avec les DIFs DIF_ALGECO 2 150 DIF SDHCAL ajoutees PULSALYS_DOME 1 State de base des 8 boards GRIC pour PULSALYS PULSALYS_DOME 2 Un test avec un seuil a 120 ... DIFTEST_DOME 1 State de base de la DIF 5 (24 Asics) DIFTEST_DOME 2 Seuil 140 ASU DIF 5 ...
mgroc --download --state=PULSALYS_DOME --version=2 PULSALYS_DOME 2 48 asics
et
ls -l /dev/shm/mgroc/ total 104 -rw-r--r-- 1 mirabito cms 104744 Jan 7 15:03 PULSALYS_DOME_2.json
Les exemples suivants sont pour un FEB, la methodologie est analogue pour les DIFs et les GRICs
Dans python (MGDBLOGIN doit être déclaré)
import MongoRoc as mg s=mg.instance() s.createNewState("FEB_B15_LYON") s.addFEB("192.168.10.15",2,"PR2B") s.uploadNewState("Un example de state avec un FEB et 2 ASICs")
et le state FEB_B15_LYON version 1 est inséré dans la base
import MongoRoc as mg s=mg.instance() s.download("FEB_B15_LYON",1) s.PR2_ChangeVthTime(495,15*256+10,1) s.PR2_ChangeVthTime(499,15*256+10,2) s.uploadChanges("FEB_B15_LYON","Threshold changed 495 on PR2_1 and 499 on 2")
import MongoRoc as mg s=mg.instance() s.download("FEB_B15_LYON",2) cor15_1= [0, 0, 0, 0, 3, 2, 2, 2, 3, 1, 1, 2, 0, 1, 1, 0,-1, 1, 1, -1, 1, 1, 1, 0, 1, 0, 1, 0, -1, 0, 2, 0] cor15_2= [0, 0, 0, 0, -2, -3, -3, -2, -2, -2, -2, -3, -2, -2, -2, -2, -2, -2, -2,-2, -2, -2, -3, -3, -2,0, -2, 0, -2, 0, -2, 0] s.PR2_Correct6BDac(15*256+10,1,cor15_1) s.PR2_Correct6BDac(15*256+10,2,cor15_2) s.uploadChanges("FEB_B15_LYON","Correction on 6BDAC on the 2 Asics")
import MongoRoc as mg s=mg.instance() s.download("FEB_B15_LYON",3) chm1=[0,1,2,3,25,27,29,31] for c in chm1: s.PR2_Change6BDac(15*256+10,1,c,1) s.PR2_ChangeMask(15*256+10,1,c,1) s.PR2_Change6BDac(15*256+10,2,c,1) s.PR2_ChangeMask(15*256+10,2,c,1) s.uploadChanges("FEB_B15_LYON","Mask unused channels ")
et on obtient:
mgroc --states | grep B15 FEB_B15_LYON 1 Un example de state avec un FEB et 2 ASICs FEB_B15_LYON 2 Threshold changed 495 on PR2_1 and 499 on 2 FEB_B15_LYON 3 Correction on 6BDAC on the 2 Asics FEB_B15_LYON 4 Mask unused channels
Les configurations du jobcontrol de zdaq sont des fichiers JSON qui doivent etre accessible sur le reseau, l'utilisation de mongodb est donc naturelle
Un fichier de configuration est un dictionnaire avec deux tags:
{ "NAME":"My_first_conf_1", "HOSTS":{ "lyopc1":[p1,p2,p3 ], "lyopc1":[p1,p2,p3,p4 ], "lyopcbuild":[p1,p2] } }
Chaque processus p est decrit par les attributs suivants:
{ "ARGS": [], "ENV": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "LD_LIBRARY_PATH=/usr/lib:/usr/local/lib:/opt/dhcal/lib:$LD_LIBRARY_PATH", "WEBPORT=41000" ], "NAME": "CCCSERVER", "PARAMETER": { "device": "DCCCCC01" <=== FTDI name }, "PROGRAM": "/opt/dhcal/bin/lydaq_daemon_Sdcc" }
{ "ARGS": [], "ENV": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "DIM_DNS_NODE=lyosdhcal10", "LD_LIBRARY_PATH=/usr/lib:/usr/local/lib:/opt/dhcal/levbdim/lib:/opt/dhcal/lib:/opt/dhcal/DQM4HEP/lib:/opt/dhcal/dim/linux:/opt/dhcal/DQM4HEP/lib:/opt/dhcal/root/lib::/opt/dhcal/lcio/v02-00/lib/:$LD_LIBRARY_PATH", "WEBPORT=42000" ], "NAME": "MDCCSERVER", "PARAMETER": { "device": "MDCC01", <== FTDI name "spilloff": 1000000, <== Spill parameters "spillon": 20000, "spillregister": 64 }, "PROGRAM": "/opt/dhcal/bin/lydaq_daemon_Mdcc" }
{ "ARGS": [], "ENV": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "LD_LIBRARY_PATH=/usr/lib:/usr/local/lib:/opt/dhcal/levbdim/lib:/opt/dhcal/lib:/opt/dhcal/DQM4HEP/lib:/opt/dhcal/dim/linux:/opt/dhcal/DQM4HEP/lib:/opt/dhcal/root/lib::/opt/dhcal/lcio/v02-00/lib/:$LD_LIBRARY_PATH", "CONFDB_WEB=cmsLyon/RPC_2008@ilcconfdb.ipnl.in2p3.fr", "WEBPORT=40000" ], "NAME": "TDCSERVER", "PARAMETER": { "publish": "tcp://lyosdhcal11:5556", <== data publication stream "tdc": { "db": { <== DB description "mode": "WEB", "state": "FEB_2B_1415_25" }, "network": "192.168.10." <== FEB network path } }, "PROGRAM": "/opt/dhcal/bin/lydaq_daemon_FebCms" }
{ "ARGS": [], "ENV": [ "PATH=/opt/dhcal/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "LD_LIBRARY_PATH=/usr/lib:/usr/local/lib:/opt/dhcal/lib:$LD_LIBRARY_PATH", "PYTHONPATH=/opt/dhcal/script/:$PYTHONPATH", "CONFDB_WEB=cmsLyon/RPC_2008@ilcconfdb.ipnl.in2p3.fr", "WEBPORT=40000", "INSTANCE=0" ], "NAME": "DIFMANAGER", "PARAMETER": { "detectorId": 100, <== Event builder detector id "dif": { "db": { <== DB access description "mode": "mongo", "state": "DIFTEST_DOME", "version": 3 } }, "publish": "tcp://lyosdhcal9:5556" <== data publication port }, "PROGRAM": "/opt/dhcal/bin/lydaq_daemon_DIF" }
{ "ARGS": [], "ENV": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "LD_LIBRARY_PATH=/usr/lib:/usr/local/lib:/opt/dhcal/lib:$LD_LIBRARY_PATH", "WEBPORT=40000", "INSTANCE=0" ], "NAME": "DIFSERVER", "PARAMETER": { "builderAddress": "tcp://lyosdhcal10:5556", <== data collection stream "dbcache": "tcp://lyosdhcal10:5555", <== DB cache (Oracle) address "detectorId": 100 }, "PROGRAM": "/opt/dhcal/bin/lydaq_daemon_Dif" }
{
"ARGS": [], "ENV": [ "LD_LIBRARY_PATH=/usr/lib:/usr/local/lib:/opt/dhcal/lib:$LD_LIBRARY_PATH", "WEBPORT=45000" ], "NAME": "FDAQ", "PARAMETER": { <== Slow control publication information "TCPPort": 5500, "location": "DOME_ALGECO_FEB2019", <== Compulsary for run start "period": 30, "s_ctrlreg": "0x815A1B00" }, "PROGRAM": "/opt/dhcal/bin/lydaq_daemon_Control" }
{ "ARGS": [], "ENV": [ "LD_LIBRARY_PATH=/opt/dhcal/root/lib:/usr/lib:/usr/local/lib:/opt/dhcal/lib:$LD_LIBRARY_PATH", "WEBPORT=46000" ], "NAME": "WRITER", "PARAMETER": { "dif": 1, "directory": "/data/NAS/TEST_BAKELITE", <== data writing directory "processor": [ <== List of data processor "binarywriter", "lydaq_pluggins_monitor", "lydaq_pluggins_rootwriter", "lydaq_pluggins_lciowriter" ], "shmpath": "/dev/shm/monitor", <== Monitoring storage directory "stream": [ <== Liste of listening ports "tcp://*:5556" ] }, "PROGRAM": "/opt/dhcal/bin/lydaq_daemon_Builder" }
{ "ARGS": [], "ENV": [ "LD_LIBRARY_PATH=/usr/lib:/usr/local/lib:/opt/dhcal/lib:$LD_LIBRARY_PATH", "CONFDB=...", <= See /etc/ljc.conf for value "CONFDB_WEB=cmsLyon/RPC_2008@ilcconfdb.ipnl.in2p3.fr", "WEBPORT=44000" ], "NAME": "DBSERVER", "PARAMETER": { "mode": "DB", "path": "/dev/shm/", "publish": "tcp://*:5555", <= publication port to DIF server application "state": "Dome_42chambres_Reference_v4_241" }, "PROGRAM": "/opt/dhcal/bin/lydaq_daemon_ConfigurationDB" }
{ "ARGS": [], "ENV": [ "LD_LIBRARY_PATH=/opt/dhcal/root/lib:/usr/lib:/usr/local/lib:/opt/dhcal/lib:$LD_LIBRARY_PATH", "WEBPORT=31000" ], "NAME": "ZUP", "PARAMETER": { "TCPPort": 5500, <= Slow control publication port "location": "SDHCAL_H2SEPT2017", "device": "/dev/ttyUSB0", <= USB port "port": 1 <= ZUP address }