Skip to main content

A command line tool for interacting with a Tango control system

Project description

Zingo!

Zingo is a command line interface to interact with a Tango control system.

It can do many of the basic tasks that are often done using Jive, but is entirely terminal driven, and tries to do things in shell-friendly ways. That means that it should work well with other shell utilities, e.g. via pipes, for further filtering or processing, or writing to files.

Note: Zingo is basically "read only" and can't be used to make changes to the Tango DB or devices. However it has limited ability to run device commands.

It can output most things in "human readable", TSV (tab separated) or JSON formats. If "rich" is installed, most commands automatically use it to show nice colored tables.

Most commands query the Tango DB, and you can use regular expressions to filter most inputs (devices, servers, properties, ...). Zingo is intended to be efficient, and tries to use minimal database queries.

Features

  • Listing devices based on filters
  • Showing information about devices
  • Listing device attributes along with their details
  • Reading device attributes, instantaneously or continuously
  • Reading and searching device and attribute properties using regexps
  • Running device commands (experimental!)
  • Collecting and presenting "black box" information about devices
  • Receiving Tango device log messages (experimental!)
  • Easy to use with other shell command like grep, cut, sort, ...

Requirements

  • python >= 3.6
  • pytango
  • (optional) rich

Installation

zingo is on PyPI and conda-forge. Install it with your preferred package manager: pip, uv, conda or pixi.

As it's intended to be used as a script, we recommend installing it globally. With uv, do:

uv tool install zingo

Add --with rich if you want fancier output with tables and colors.

Usage

To get a summary of all commands and global options, use zingo --help. Help on individual commands is available as zingo <cmd> --help.

If rich is installed, you should get some nicely formatted tables of output by default, unless piping to another command. However this can be annoying if the output is very wide. You can turn the tables off by adding the --raw argument.

Here follow some examples.

Devices

Show information about all devices of a certain class (regex allowed)

$ zingo dev --class TangoTest
name           state    class      instance        host
sys/tg_test/1  RUNNING  TangoTest  TangoTest/test  w-johfor-pc-0

Show more details about a device (several devices can be given, or you can use regex to match many)

$ zingo dev sys/tg_test/1 --details
name           class      instance        host           started                      stopped                      error
sys/tg_test/1  TangoTest  TangoTest/test  w-johfor-pc-0  29th April 2021 at 08:38:56  29th April 2021 at 08:38:55

List the names of all motors in a given sardana pool

$ zingo dev --class Motor --server Pool/1 -l
motor/motctrl02/1
motor/motctrl02/2
motor/motctrl02/3
motor/motctrl02/4

(The "-l" flag means that zingo will only output the names, which is often what you want for further shell scripting.)

Attributes

List all attributes of some devices:

$ zingo attr sys/tg_test/1 sys/tg_test/2
sys/tg_test/1  ampli
sys/tg_test/1  boolean_scalar
sys/tg_test/1  double_scalar
sys/tg_test/1  double_scalar_rww
...
sys/tg_test/2  ampli
sys/tg_test/2  boolean_scalar
sys/tg_test/2  double_scalar
sys/tg_test/2  double_scalar_rww
...

Show all attributes of a device, with some details:

$ zingo attr sys/tg_test/1 -d
sys/tg_test/1  State                DevState    SCALAR       READ
sys/tg_test/1  Status               DevString   SCALAR       READ
sys/tg_test/1  ampli                DevDouble   SCALAR       WRITE
...

(There are more flags for further information, see zingo attr --help)

Read some attributes of some devices:

$ zingo read x1/alarm/bfkyduw x1/alarm/vbztd -a state -a Status
x1/alarm/bfkyduw	state	ON
x1/alarm/bfkyduw	Status	The device is in ON state.
x1/alarm/vbztd	state	ON
x1/alarm/vbztd	Status	The device is in ON state.

The -c (--continuous) flag means that Zingo will keep reading and printing values until interrupted. It will try to subscribe to attribute change events. If not available, it falls back to polling. If you want polling in any case, use the -f (--force-polling) flag. You can control the polling period with -p (--period).

Properties

Read some properties of a device:

$ zingo prop sys/tg_test/2 -p polled_attr -p OtherProp
Device         Property     Line  Value
sys/tg_test/2  polled_attr  0     boolean_scalar
sys/tg_test/2  polled_attr  1     3000
sys/tg_test/2  OtherProp    0     I am another property!

Search for the value "8762" in device properties of devices matching a pattern:

$ zingo prop "sys/tg_test/.*" --search 8762

By instead using the attrprop command, we can do similar things with attribute properties.

For writing properties from the shell, I recommend the official tango_admin utility, as this is currently outside of the scope of zingo. Or, for more controlled usage, use dsconfig (can be installed with pip).

Commands

Works a lot like reading attributes, except that some commands require arguments, which you can specify with the -a switch:

$ zingo cmd sys/tg_test/1 -c DevFloat -a 123.456
device         command   arguments  line  value               error
sys/tg_test/1  DevFloat  123.456    0     123.45600128173828

If the command takes multiple arguments, just add more:

$ zingo cmd sys/tg_test/1 -c DevVarULongArray -a 1 -a 1231 -a 231321313

Zingo will try its best to convert what you give into the proper Tango data types. For booleans use e.g. true or False.

Warning: running commands can affect the operation of Tango devices, so be very careful when using this in an real environment!

Shell tricks

Combine Zingo with other shell tools to do much more sophisticated things:

Count how many of a set of devices are in some given state (-r is a shortcut for reading State of each matching device):

$ zingo dev ".*alarm.*" -r | grep -w ALARM | wc -l
7

(Here, "-w" to grep ensures that we only match on the stand-alone word "ALARM", not the letters "ALARM" e.g. as part of a device name. Also, note that surrounding the device pattern with quotes ensures that the shell doesn't try to match it against the filesytem.)

Piping the output of zingo back into zingo can be useful! Read the Status attribute on all power supplies that are in FAULT:

$ zingo dev --class PowerSupply -r | grep -w FAULT | cut -f1 | xargs zingo read -a Status
ps/0/agcsfzptuo	Status	Could not connect to hardware.
ps/3/byqrmze	Status	Hardware reports error 871.
ps/4/deciqvgf	Status	Hardware reports error 98.
...

(Here, "cut" is used to get only the first field of the output - the device names - and "xargs" is used to insert the results into the commandline of the second call to zingo.)

Black box

The "black box" is a low level Tango feature that shows the latest client calls to a given device. It is sometimes very useful for diagnosing issues but can be cumbersome to use. Zingo wraps this functionality to make it a bit more accessible. The bbox command can be pointed it to one or more devices. It has three modes of operation:

  • If no flags are given, it will retrieve the "black box" info once from each device and print it out in a slightly more readable fashion.
  • With the --tail flag, "black box" will be called on the device(s) periodically, and new events are printed out as they come in, until interrupted by Ctrl+C. Somewhat like tailing a logfile.
  • With the --statistics flag, the command will collect "black box" information periodically until interrupted. Then it prints out a summary of the calls, most common first.

Note that a limitation of the black box is that it stores (by default) only the 50 latest events each time it's called. That means that if the frequency of client calls is very high, you may miss events. It's not possible to avoid this in general, but zingo will warn if the risk exists. The --period flag can be used to increase the rate of calls if this is an issue. On the other hand, increasing the frequency too much can result in the actual "black box" calls dominating the statistics :)

To filter out the blackbox calls themselves (which are usually not interesting):

$ zingo bbox -f sys/tg_test/1 | grep -v blackbox

Tango Logging (experimental)

Zingo has experimental support for the "Tango logging system". The idea is to attach to a running, remote device (or several), set a log level and print any log messages on the terminal as they arrive. Use Ctrl-C to exit.

$ zingo log sys/tg_test/1 -l 5
2021-06-29T17:19:20.444000	DEBUG	sys/tg_test/2	DataGenerator::generating data
2021-06-29T17:19:22.029000	DEBUG	sys/tg_test/2	TangoTest::always_executed_hook()  sys/tg_test/2
2021-06-29T17:19:22.029000	DEBUG	sys/tg_test/2	TangoTest::read_attr_hardware(vector<long> &attr_list) entering...
...

The log level given corresponds to the "trace level" that can be set when starting a Tango server, using -v (see log --help for a detailed list)

Note: the previous logging settings should be restored when the program exits (on break), but this is a hacky solution and it's not well tested. The logging settings are not changed permamently and will be restored anyway at the next device restart.

Note: this feature can only pick up log messages that go through the Tango logging system, not e.g. if a normal python logger is used in the device code.

Under the hood, zingo creates a temporary "nodb" device, conforming to the Tango logger standard, running in-process, and configures the remote device to talk directly to this logger device. This way no new device is created in the Tango database, however there is some trace left in the remote device's __SubDevice property. This should have no impact on the control system but may look slightly strange. It is always called zingo/<your local username>/logger.

It's possible that Tango gets confused about hostnames. For this command to work, communication must be established between the remote Tango device and Zingo. Zingo tries to guess which hostname to use, but if you know what your own hostname is "supposed" to be, you can specify it using --host. You can also specify which port to use for communication using --port. Otherwise a random free port will be selected, which is usually fine, but network setups may vary.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

zingo-1.1.0.tar.gz (42.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

zingo-1.1.0-py3-none-any.whl (37.7 kB view details)

Uploaded Python 3

File details

Details for the file zingo-1.1.0.tar.gz.

File metadata

  • Download URL: zingo-1.1.0.tar.gz
  • Upload date:
  • Size: 42.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for zingo-1.1.0.tar.gz
Algorithm Hash digest
SHA256 d393570fdc3f45aaa07e152343141f07aaf22566a11fa860b1258e3e4a40d7af
MD5 71df33978103e041e05bf15654e796a4
BLAKE2b-256 e4c5e180363701a25263864c82b06353ca489f303886439254d87984d6a2925c

See more details on using hashes here.

File details

Details for the file zingo-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: zingo-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 37.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for zingo-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 fb816e59b2571cd73bbdb40f190d152b31a091c780ead9577d5967a4e34f9ba7
MD5 0996f49cbb5e8d5a9802224354bfcb3f
BLAKE2b-256 3241adca8ae531a4a4af62e485e3a7648d510b8e72c4a93e8cd47c844699e776

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page