Device2
Overview
This is a client-server system for accessing devices and programs in experimental setups. Previous version was a tcl library ( https://github.com/slazav/tcl-device ) with a few annoying limitations.
There is a server which work with "devices". They can be physical devices connected in various ways or programs with special interface. Each device has a unique name, which is listed in the server configuration file. Server knows how to open a device, send it a message and receive answer.
Clients can connect to the server using HTTP protocol and send messages to devices. This architecture has many advantages comparing to direct connections between clients and devices:
-
Clients know nothing about device connection details, they should use only device name to access it. All low-level connection parameters (e.g. serial port configuration) are managed by the server.
-
Multiple clients can access a single device without collisions. All needed lockings are done by the server. A client can also lock a device for single use, preventing others from accessing it.
-
A device is opened on demand, then the fist client start using it and closed then all users disconnected. Client should keep a permanent connection to the server if it wants to use a device without closing/opening it.
-
Any client can monitor all messages for any device.
-
Remote access to devices can be easily implemented in this system by either making a tunnel for HTTP connections, or by attaching the remote client program,
device_c
to the local server as a device.
The server support devices connected via linux-gpib and usbtmc kernel drivers; serial and network devices (including LXI); programs with SPP interface.
Server
HTTP communication with the server
Clients communicate with the server using GET requests of HTTP protocol.
URLs with up to three components are used: <action>/<device>/<message>
.
(Note that symbol /
is not allowed in device names). For example, a
request to http://<server>:<port>/ask/generator/FREQ?
" sends phrase
FREQ?
to the device generator
and returns answer.
On success a response with code 200 and answer of the device in the
message body is returned. On error a response with code 400 is returned.
Error description is written in Error
header and in the message body.
The server does not know what it sends to a device and what answer is expected, it just provides connection. For the next layer see DeviceRole library. It defines certain "roles" for devices with common high-level commands (e.g. "generator" role has a "set frequency" command).
Supported actions:
-
ask/<device>/<message>
-- Send message to a device, return answer. -
devices
orlist
-- Show list of all known devices. -
info/<device>
-- Print information about a device. -
reload
-- Reload device configuration. If case of errors in the file old configuration is kept. -
close/<device>
-- Close device. It will be reopened if needed. -
ping
-- Check connection to the server. Returns nothing. -
get_time
-- Get system time (unix seconds with microsecond precision) -
use/<device>
-- Use a device in this connection. Usually a device is opened (if it is not opened yet) on demand, thenask
action is called. This action can be used to open and check the device before sending any message to it (e.g. to process errors separately). -
release/<device>
-- Notify the server that this device is not going to be used by this connection anymore. Device is closed if no other connections use it. Normally devices are closed when session is ended and no other sessions are using the device. -
log_start/<device>
-- Any user can see all communications of every device. To do it one should start withlog_start
action. The buffer of size 1024 lines is created for this connection, all messages send to the device, all answers and errors received will be written to the buffer (with "<<", ">>", and "EE" prefixes). If the buffer already exists it will be cleared. -
log_finish/<device>
-- Stop logging, delete the log buffer for this connection. -
log_get/<device>
-- Get contents of the log buffer, clear it. If logging is stopped return error. -
lock/<device>
-- Lock the device for single use. Normally no locking is needed, many clients can communicate with the device without collisions. But in some cases one may want to lock the device to prevent others from using it. This is done by thelock
action, only if the device has no other users. -
unlock/<device>
-- Unlock the device previously locked with thelock
command. -
set_conn_name/<name>
-- Set connection name. Each connection to the server has a unique number and unique text name (by default it is "#<conn_number>"). Client can change the name using this function. Name set by user can not start with "#". If name is empty, the default value "#<conn_number>" is set. If name already belongs to another connection error occures. This feature can be used to detect another instances of the same program. -
get_conn_name
-- Get connection name. -
list_conn_names
-- List all connections. -
release_all
-- Release (and unlock) all devices, reset connection name to default value.
There are two problems with locks and unique connection names (and generally with session handling):
-
If server is restarted, connections are reopened and clients do not know about it. Locks and connection names will be lost in this situation. It is recommended to update locks and names regularly, e.g. at the beginning of each measurement cycle.
-
Server can keep the connection when the client program already finished. Locks and connection name are still there, and can affect the client if it will restart connection (e.g if the program is restarted). It is recommended to run
release_all
action to unlocked devices and reset connection name to default value before disconnecting.
Starting the server
Usage:
device_d <options>
Options:
-C, --cfgfile <arg>
-- Server configuration file (default:/etc/device/device_d.cfg
).-D, --devfile <arg>
-- Device list file (default:/etc/device/devices.cfg
).-a, --addr <arg>
-- IP address to listen. Use "*" to listen everywhere (default:127.0.0.1
).-p, --port <arg>
-- TCP port for connections (default:8082
).-f, --dofork
-- Do fork and run as a daemon.-S, --stop
-- Stop running daemon (found by pid-file).-R, --reload
-- Reload configuration of running daemon (found by pid-file).-U, --user <arg>
-- Run as user (default: empty, do not switch user).-v, --verbose <arg>
-- Verbosity level (default: 1):- 0 - write nothing;
- 1 - write some information on server start/stop;
- 2 - write about opening/closing connections and devices;
- 3 - write all messages sent to devices and received from them.
-l, --logfile <arg>
-- Log file, "-" for stdout. (default:/var/log/device_d.log
in daemon mode, "-" in console mode.-P, --pidfile <arg>
-- Pid file (default:/var/run/device_d.pid
)--test
-- Test mode with connection number limited to 1.-h, --help
-- Print help message and exit.--pod
-- Print help message in POD format and exit.
Configuration file: Server configuration file can be used to override
default values for some of the command-line options. Following parameters
can be set in the configuration file: addr
, port
, logfile
,
pidfile
, devfile
, user
, verbose
The file contains one line per parameter. Empty lines and comments (starting
with #
) are allowed. A few lines can be joined by adding symbol \
before end of line. Words can be quoted by single or double quotes.
Special symbols (#
, \
, quotes) can be typed by adding \
in front of
them. Case of characters is important. Each non-empty, non-comment line
should have the form:
<parameter name> <parameter value>
Signal handling: server exits on SIGTERM, SIGINT, SIGQUIT signals. Device
list is re-read on SIGHUP signal. If device_d
program is called with
--stop
/--reload
parameter it will send SIGTERM/SIGHUP to a running
server (found by pid-file). Reloading can be also done by any client
with reload
action.
Device list file
Default location of the device configuration file is
/etc/device2/devices.cfg
It can be changed with server command-line
option -D
or in the server configuration file.
The file contains one line per device. Empty lines and comments (starting
with #
) are allowed. A few lines can be joined by adding symbol \
before end of line. Words can be quoted by single or double quotes.
Special symbols (#
, \
, quotes) can be typed by adding \
in front of
them. Case of characters is important. Each non-empty, non-comment line
should have the form:
<device name> <driver name> [-<parameter> <value> ...]
Device name should be non-empty and should not contain
, \n
, \t
,
\
and /
characters.
Parameters are driver-specific.
If the file contains errors server prints error message in the log and
keep old configuration (if any). If after starting the server you see no
devices in the list
action output, try to do reload
and see error
message.
Available drivers:
-
test
-- a dummy driver for tests. -
spp
-- a "Simple Pipe protocol", talking with programs. Works. -
usbtmc
-- for USB devises connect via usbtmc kernel module (Agilent/Kesight devices). Works. -
serial
-- RS232 connections with full control of the serial port. Base for other serial_* drivers. -
serial_asm340
-- Driver for Pfeiffer Adixen ASM340 leak detector connected via RS232 (null-modem cable). Leak detector should be in Advanced I/O mode. Works. -
serial_l300
-- Driver for Phoenix/Leybold L300i leak detector connected via RS232 (normal cable, not null-modem). Leak detector settings (in Menu/Settings/Interfaces): Control locations: ALL or RS232; RS232 settings: 19200 LF -- 8N1 -- ASCII. Works. -
serial_vs_ld
-- Driver for Agilent VS leak detector. Leak detector should be connected with null-modem cable. -
serial_tenma_ps
-- Driver for Korad/Velleman/Tenma power supplies. Works. -
serial_et
-- Driver for EastTester devices. Works with E4502 LCR meter. -
serial_simple
-- Serial driver with reasonable default settings. Works with old Agilent/HP/Keythley devices. -
net
-- Network connections. By default it works with LXI devices. -
net_gpib_prologix
-- Driver for Prologix gpib2eth converter. Not tested. -
gpib
-- for devices connected via linux-gpib library. Works.
test
-- a dummy driver for tests
Driver Just repeats any message sent to it.
Parameters: none
spp
-- programs following "Simple Pipe protocol"
Driver This driver implements "Simple pipe protocol" for communicating with
programs using stdin/stdout unix pipes. The protocol is described in
https://github.com/slazav/tcl-device (see Readme.md) It is used in a few
of my projects (pico_rec, graphene), and in device_c
client program.
Parameters:
-
-prog
-- Program name. Required. -
-open_timeout
-- Timeout for opening, seconds. Default 20.0. -
-read_timeout
-- Timeout for reading, seconds. Default: 10.0. -
-errpref
-- Prefix for error messages. Default "spp: ". -
-idn
-- Override output of *idn? command. Default: do not override.
usbtmc
-- USB devices using usbtmc kernel module
Driver This driver supports devices connected via usbtmc kernel driver. It should work with all usual Agilent/Keysight devices connected via USB. Read timeout is set internally in the driver (5s by default?) but can be modified by -timeout parameter.
By default the driver reads answer from the device only if there is a question mark '?' in the first word of the message.
Parameters:
-
-dev <v>
-- Serial device filename (e.g. /dev/usbtmc0) Required. -
-timeout <v>
-- Timeout for reading, seconds Default: 5.0 -
-delay <v>
-- Delay after write command, s. Default: 0.01 -
-errpref <v>
-- Prefix for error messages. Default "usbtmc: ". -
-idn <v>
-- Override output of *idn? command. Default: do not override. -
-read_cond <v>
-- When do we need to read answer from a command:always
,never
,qmark
(if there is a question mark in the message), qmark1w (question mark in the first word). Default:qmark1w
. -
-add_str <v>
-- Add string to each message sent to the device. Default: "\n" -
-trim_str <v>
-- Remove string from the end of received messages. Default: "\n"
Driver "gpib" -- GPIB devices using linux-gpib library
By default the driver reads answer from the device only if there is a question mark '?' in the first word of the message.
Parameters:
-
-addr <N>
-- GPIB address. Required. -
-board <N>
-- GPIB board number. Default: 0. -
-timeout <str>
-- I/O timeout: none, 10us, 30us, 100us ... 300s, 1000s Default 10s. -
-open_timeout <str>
-- Open timeout, same values as for -read_timeout. Default 3s. -
-eot (1|0)
-- Enable/disable assertion of EOI line with last data byte Default: do not change -
-eos_mode <v>
-- Set end-of-string flags, any combination of R X B characters for REOS, XEOS, BIN flags. Only works with -eos option. Default: empty -
-eos (0..255)
-- Set end-of-string character. Default: do not change -
-secondary (1|0)
-- Set secondary GPIB address. -
-bufsize <N>
-- Buffer size for reading. Maximum length of read data. Default: 4096 -
-errpref <str>
-- Prefix for error messages. Default: "gpib: " -
-idn <str>
-- Override output of *idn? command. Default: empty string, do not override. -
-read_cond <v>
-- When do we need to read answer from a command:always
,never
,qmark
(if there is a question mark in the message), qmark1w (question mark in the first word). Default:qmark1w
. -
-add_str <v>
-- Add string to each message sent to the device. Default: "\n" -
-trim_str <v>
-- Remove string from the end of received messages. Default: "\n" -
-delay <v>
-- Delay after write command, s. Default: 0
net
-- network devices
Driver By default the driver reads answer from the device only if there is a question mark '?' in the first word of the message.
Defaults parameters correspond to LXI raw protocol.
Parameters:
-
-addr
-- Network address or IP. Required. -
-port <N>
-- Port number. Default: "5025" (lxi raw protocol). -
-timeout <N>
-- Read timeout, seconds. No timeout if <=0. Default 5.0. -
-delay <v>
-- Delay after write command, s. -
-open_delay <v>
-- Delay before opening a connection, s. Default: 0.0. This could be useful for some strange devices (Siglent power supplies) which need some time between closing previous connection and opening a new one. Default: 0 -
-bufsize <N>
-- Buffer size for reading. Maximum length of read data. Default: 4096 -
-errpref <str>
-- Prefix for error messages. Default: "Driver_net: " -
-idn <str>
-- Override output of *idn? command. Default: empty string, do not override. -
-read_cond <v>
-- When do we need to read answer from a command:always
,never
,qmark
(if there is a question mark in the message), qmark1w (question mark in the first word). Default:qmark1w
. -
-add_str <v>
-- Add string to each message sent to the device. Default: "\n" -
-trim_str <v>
-- Remove string from the end of received messages. Default: "\n"
net_gpib_prologix
-- devices connected via Prologix gpib2eth converter
Driver Not tested!
Parameters:
-addr <v>
-- Network address or IP. Required.-port <v>
-- Port number. Default: "1234".-timeout <v>
-- Read timeout, seconds. No timeout if <=0. Default 5.0.-bufsize <v>
-- Buffer size for reading. Maximum length of read data. Default: 4096-errpref <v>
-- Prefix for error messages. Default: "Driver_net: "-idn <v>
-- Override output of *idn? command. Default: empty string, do not override.-addr <v>
-- GPIB address
serial
-- Serial devices
Driver This is a very general driver with lots of parameters.
See: Serial Programming Guide for POSIX Operating Systems (https://www.cmrr.umn.edu/~strupp/serial.html)
, stty(1)
, tcsetattr(3)
.
Other serial drivers are based on it. As an example, configuration of Pfeiffer ASM340 leak detector can be written as
asm340a serial \
-dev /dev/ttyUSB0 -speed 9600 -parity 8N1 -cread 1 -clocal 1\
-timeout 2.0 -vmin 0 -ndelay 0 -icrnl 0\
-sfc 1 -raw 1 -errpref "ASM340: " -delay 0\
-ack_str \x06 -nack_str \x15 -add_str \r -trim_str \r
but there is a special driver which set all needed parameters:
asm340b serial_asm340 -dev /dev/ttyUSB0
Note that most options have no defaults: if such an option is not set then the linux serial port setting is left untouched.
Parameters: serial port setup.
-
-dev <name>
-- Serial device filename (e.g. /dev/ttyUSB0) Required. -
-ndelay (1|0)
-- Non-blocking mode Default: do not change. -
-speed <N>
-- Baud rate (both input and output), integer value. POSIX values: 0,50,75,110,134,150,200,300,600,1200, 1800,2400,4800,9600,19200,38400. Non-POSIX values: 57600, 115200, 230400, 460800, 500000, 576000, 921600, 1000000, 1152000, 1500000, 2000000, 2500000, 3000000, 3000000, 3500000, 4000000. Default: do not change. -
-ispeed <N>
-- input boud rate -
-ospeed <N>
-- output boud rate
Parameters: stty control options
If option is missing no change is made.
-clocal (1|0)
-- disable modem control signals-cread (1|0)
-- allow input to be received-crtscts (1|0)
-- enable RTS/CTS handshaking-cs <N>
-- set character size to N bits, N in [5..8]-cstopb (1|0)
-- use two stop bits per character-hup (1|0)
-- send a hangup signal when the last process closes the tty-parenb (1|0)
-- generate parity bit in output and expect parity bit in input-parodd (1|0)
-- set odd parity (or even parity with '-')-cmspar (1|0)
-- use "stick" (mark/space) parity
Parameters: stty input settings
If option is missing no change is made.
-icrnl (1|0)
-- translate carriage return to newline-inlcr (1|0)
-- translate newline to carriage return-igncr (1|0)
-- ignore carriage return-iuclc (1|0)
-- translate uppercase characters to lowercase-iutf8 (1|0)
-- assume input characters are UTF-8 encoded-brkint (1|0)
-- breaks cause an interrupt signal-ignbrk (1|0)
-- ignore break characters-imaxbel (1|0)
-- beep and do not flush a full input buffer on a character-inpck (1|0)
-- enable input parity checking-ignpar (1|0)
-- ignore characters with parity errors-istrip (1|0)
-- clear high (8th) bit of input characters-parmrk (1|0)
-- mark parity errors (with a 255-0-character sequence)-ixany (1|0)
-- let any character restart output, not only start character-ixoff (1|0)
-- enable sending of start/stop characters-ixon (1|0)
-- enable XON/XOFF flow control
Parameters: stty output settins
If option is missing no change is made.
-bs <N>
-- backspace delay style, N in [0..1] (no delay, 100ms)-cr <N>
-- carriage return delay style, N in [0..3] (no delay, column-dep, 100ms, 150ms)-ff <N>
-- form feed delay style, N in [0..1] (no delay, 2s)-nl <N>
-- newline delay style, N in [0..1] (no delay, 100ms)-tab <N>
-- horizontal tab delay style, N in [0..3] (no delay, column-dep, 100ms, tab to space)-vt <N>
-- vertical tab delay style, N in [0..1] (no delay, 2s)-ocrnl (1|0)
-- translate carriage return to newline-onlcr (1|0)
-- translate newline to carriage return-newline-onlret (1|0)
-- newline performs a carriage return-onocr (1|0)
-- do not print carriage returns in the first column-ofdel (1|0)
-- use delete characters for fill instead of NUL characters-ofill (1|0)
-- use fill (padding) characters instead of timing for delays-olcuc (1|0)
-- translate lowercase characters to uppercase-opost (1|0)
-- postprocess output
Parameters: stty local settings.
If option is missing no change is made.
-echo (1|0)
-- echo input characters-echoctl (1|0)
-- echo control characters in hat notation ('^c')-echoe (1|0)
-- echo erase characters as backspace-space-backspace-echok (1|0)
-- echo a newline after a kill character-echoke (1|0)
-- BS-SP-BS entire line on line kill-echonl (1|0)
-- echo newline even if not echoing other characters-echoprt (1|0)
-- echo erased characters backward, between '' and '/'-extproc (1|0)
-- enable "LINEMODE"; useful with high latency links-flusho (1|0)
-- discard output-icanon (1|0)
-- enable special characters: erase, kill, werase, rprnt (canonical input)-iexten (1|0)
-- enable non-POSIX special characters-isig (1|0)
-- enable interrupt, quit, and suspend special characters-noflsh (1|0)
-- disable flushing after interrupt and quit special characters-tostop (1|0)
-- stop background jobs that try to write to the terminal-xcase (1|0)
-- with icanon, escape with '' for uppercase characters (obsolete?)
Parameters: combination settings
Different from stty(1) options! If option is missing no change is made.
-
-parity <V>
-- Parity (8N1, 7N1, 7O1, 7S1). -
-raw (1|0)
-- Raw/canonical input. canonical input: +icanon +echo +echoe +isig raw input: -icanon -echo -echoe -
-sfc (1|0)
-- Enable/disable software flow control (ixon ixof ixany) -
-nlcnv (1|0)
-- Enable/disable newline conversion NL->NL+CR, CR->NL (icrnl, onlcr) opost should be enabled for onlcr? -
-lcase (1|0)
-- Enable/disable upper to lower case conversion (iuclc, olcuc) opost should be enabled for olcuc? -
-timeout <v>
-- Timeout in seconds, [0..25.5] s. Only valid in blocking, raw input mode (-raw=1 -ndelay=0). -
-vmin <N>
-- min number of characters [0..255] Only valid in blocking, raw input mode (-raw=1 -ndelay=0).
Parameters: other
-
-delay <v>
-- Delay after write command, s. Default: 0.1 -
-errpref <v>
-- Prefix for error messages. Default: "serial: " -
-idn <v>
-- Override output of *idn? command. Default: empty string, do not override. -
-add_str <v>
-- Add string to each message sent to the device. Note: using terminal setting -onlcr you can convert NL to NL+CR Default: empty string -
-trim_str <v>
-- Remove string from the end of received messages. Default: empty string -
-ack_str <v>
-
-nack_str <v>
-- Some devices send ack/nack sequences at the end of each message. It can be ack/nack characters (0x9/0x15), or "ok"/"#?" strings. if -ack option is set then reading is done until ack (or nack if it is set too) sequence is met. The sequences are removed from the output message; error is returned if nack received. Default: empty strings. -
-read_cond <v>
-- When do we need to read answer from a command: always, never, qmark (there is a question mark in the message), qmark1w (question mark in the first word). Default: always. -
-flush_on_err (0|1)
-- Flush serial buffers if Input/output error happens. Default: 1
serial_simple
-- Serial driver with reasonable default settings.
Driver Should work with old Agilent/HP devices.
Parameters:
-
-dev <name>
-- Serial device filename (e.g. /dev/ttyUSB0). Required. -
-timeout <v>
-- Read timeout, seconds [0 .. 25.5]. Default: 5.0 -
-sfc (0|1)
-- Software flow control. Default: 1 -
-errpref <v>
-- Prefix for error messages. Default "serial: ". -
-idn <v>
-- Override output of *idn? command. Default: do not override. -
-read_cond <v>
-- When do we need to read answer from a command: always, never, qmark (if there is a question mark in the message), qmark1w (question mark in the first word). Default: qmark1w.
Same as
serial -speed 9600 -parity 8N1 -cread 1 clocal 1\
-vmin 0 -ndelay 0 -icrnl 1 -raw 1 -sfc 1 -delay 0.1\
-opost 0 -add_str "\n" -trim_str "\n" -read_cond qmark1w\
-timeout 5.0"
serial_asm340
-- Pfeiffer Adixen ASM340 leak detector
Driver Leak detector should be in Advanced I/O mode and connected with null-modem cable.
Parameters:
-
-dev <v>
-- Serial device filename (e.g. /dev/ttyUSB0) Required. -
-timeout <v>
-- Read timeout, seconds [0 .. 25.5] Default: 5.0 -
-sfc (0|1)
-- Software flow control (both 0 and 1 should work). Default: 1 -
-errpref <str>
-- Prefix for error messages. Default "ASM340: " -
-idn <v>
-- Override output of *idn? command. Default: "Adixen ASM340 leak detector"
Same as
serial -speed 9600 -parity 8N1 -cread 1 clocal 1\
-vmin 0 -ndelay 0 -icrnl 0 -raw 1 -sfc 1 -delay 0\
-opost 1 -lcase 1 -ack_str "\x06" -nack_str "\x15"\
-add_str "\r" -trim_str "\r" -read_cond always\
-timeout 5.0 -errpref "ASM340: " -idn "Adixen ASM340 leak detector"
serial_l300
-- Phoenix/Leybold L300i leak detector
Driver Leak detector settings:
- Menu/Settings/Interfaces/Control locations: ALL or RS232
- Menu/Settings/Interfaces/RS232: 19200 LF -- 8N1 -- ASCII
Cable: normal RS232, not null-modem. Hardware handshake is disabled in the driver, there is no need to use special cable to emulate it.
SCPI Command set is very similar to one of inficon Modul1000 leak detector.
Parameters:
-
-dev <v>
-- Serial device filename (e.g. /dev/ttyUSB0) Required. -
-timeout <v>
-- Read timeout, seconds [0 .. 25.5] Default: 5.0 -
-errpref <str>
-- Prefix for error messages. Default "ASM340: " -
-idn <v>
-- Override output of *idn? command. Default: "Adixen ASM340 leak detector"
Same as
serial -speed 19200 -parity "8N1"\
-cread 1 -clocal 1 -icrnl 0 -raw 1 -sfc 1 -crtscts 0\
-add_str "\r" -trim_str "\r" -read_cond always\
-timeout 5.0 -errpref "L300: " -idn "PhoeniXL300"
serial_vs_ld
-- Agilent VS leak detector
Driver Leak detector should be connected with null-modem cable.
Parameters:
-
-dev <str>
-- Serial device filename (e.g. /dev/ttyUSB0) Required. -
-timeout <v>
-- Read timeout, seconds [0 .. 25.5] Default: 5.0 -
-errpref <v>
-- Prefix for error messages. Default "Agilent VS: " -
-idn <v>
-- Override output of *idn? command. Default: "Agilent VS leak detector"
serial_tenma_ps
-- Korad/Velleman/Tenma power supplies
Driver Parameters:
-
-dev <v>
-- Serial device filename (e.g. /dev/ttyACM0) Required. -
-timeout <v>
-- Read timeout, seconds [0 .. 25.5] Default: 5.0 -
-errpref <v>
-- Prefix for error messages. Default "TenmaPS: " -
-idn <v>
-- Override output of *idn? command. Default: do not override.
Same as
serial -speed 9600 -parity 8N1 -cread 1 clocal 1\
-vmin 0 -ndelay 0 -sfc 0 -raw 1 -delay 0.1\
-opost 1 -olcuc 1 -read_cond qmark\
-timeout 5.0 -errpref "TenmaPS: "
Note important setting:
-
-sfc 0
: Software flow control should be off. This allows receiving zero status byte (if OVC, OVP is off and output is off).-raw 1
is also needed to pass special characters. -
-delay 0.1
: It should be a delay between sending command to the device and reading answer.
serial_et
-- EastTester devices
Driver Parameters:
-
-dev <v>
-- Serial device filename (e.g. /dev/ttyACM0) Required. -
-timeout <v>
-- Read timeout, seconds [0 .. 25.5] Default: 2.0 -
-errpref <v>
-- Prefix for error messages. Default "EastTester: " -
-idn <v>
-- Override output of *idn? command. Default: do not override.
Same as
serial -speed 9600 -parity 8N1 -cread 1 clocal 1\
-ndelay 1 -sfc 1 -raw 1 -delay 0.1\
-add_str \n -trim_str "\n\n" -read_cond always
-timeout 2.0 -errpref "EastTester: "
Client
Program device_c
is a command-line client for working with the server.
Usage:
device_c [<options>] ask <dev> <msg> ...
-- send message to the device, print answerdevice_c [<options>] use_dev <dev>
-- SPP interface to a devicedevice_c [<options>] use_srv
-- SPP interface to the serverdevice_c [<options>] (list|devices)
-- print list of available devicesdevice_c [<options>] info <dev>
-- print information about devicedevice_c [<options>] reload
-- reload device configurationdevice_c [<options>] close
-- close device (it will be reopened if needed)device_c [<options>] monitor <dev>
-- monitor all communication of the devicedevice_c [<options>] ping
-- check if the server is workingdevice_c [<options>] get_time
-- get server system timedevice_c [<options>] get_srv
-- get server address
Options:
-s, --server <arg>
-- Server (default: localhost).-p, --port <arg>
-- Port (default: 8082).-v, --via <arg>
-- Connect to the server through a tunnel. Argument: name of the gateway.--via_cmd <arg>
-- Specify command template for making the tunnel, with $L, $R, $H, and $G for local port, remote port, remote host and gateway. Default: /usr/bin/ssh -f -L "$L":"$H":"$R" "$G" sleep 20-l, --lock
-- Lock the device (only foruse_dev
action).-h, --help
-- Print help message and exit.--pod
-- Print help message in POD format and exit.
Client configuration file (/etc/device/device_c.cfg
) is similar to the
server one. Following parameters can be set in the configuration file:
server
, port
, via
, via_cmd
.
Examples
Get device list. There are two devices available:
$ device_c list
graphene
test
Get information about a device. The device uses spp
driver which runs program graphene -i
and talks with it using SPP interface. It is not used by anybody (and thus closed).
$ device_c info graphene
Device: graphene
Driver: spp
Driver arguments:
-prog: graphene -i
Device is closed
Number of users: 0
Send message to a device and get answer. In this case we send get_time
command to
the graphene
device:
$ device_c ask graphene get_time
1601282446.214037
Send message to a device and get answer. Create a database with FLOAT values
using the graphene
device:
$ device_c ask graphene create new_db FLOAT "my new database"
1601282446.214037
The server also has get_time
action to get system time on the server:
$ device_c get_time
1601284005.581721
Use a device for multiple queries, without reopening it. In this case SPP protocol
is used: each message is followed by #OK
or #Error <message>
line.
Every input line is sent to the device as-is, answer is returned.
$ device_c use_dev graphene
#SPP001
Server: http://localhost:8082
Device: graphene
#OK
bad_command
#Error: Unknown command: bad_command
get_time 0
#Error: too many parameters
get_time
1601284282.200903
#OK
Use the server for multiple queries. In this mode you have access to all
server actions and can work with multiple devices. Every input line is
split into three words: action
, device
, and message
. The
read_words
library ( https://github.com/slazav/mapsoft2-libs/tree/master/read_words ) is used
to enable quotes, escape characters, multiline input etc. For example, if
you want to use spaces in the message, quote it.
$ device_c use_srv
#SPP001
Server: http://localhost:8082
#OK
ask graphene get_time
1601284389.596303
#OK
list
graphene
test
#OK
info graphene
Device: graphene
Driver: spp
Driver arguments:
-prog: graphene -i
Device is open
Number of users: 1
You are currently using the device
#OK
Remote use and how to crash the server
There are two ways how to configure remote access to your devices. First,
you can connect to the remote server by HTTP protocol. Note that device
server does not have any security features, and it's not safe to allow
connections from outside. But it should be safe to make an ssh tunnel to
the remote server. This can be done with -via parameter of device_c
command.
Other option is to use external devices connected to the local server.
The device_c
program implements SPP protocol when using in use_dev
and use_srv
modes. Thus it can be used as a device. If you have device
servers running on both computers and want to access remote device
mydev
, just write in the local configuration something like this:
mydev spp -prog "ssh comp2 device_c use_dev mydev"
This approach allows you to mix local and remote devices on your computer and access them through the local server. Note that in this configuration you should have timeouts of the spp driver larger then timeouts of the device's driver. Currently default read/open timeouts are: 10s/20s for spp, 3s/10s for gpib, 5s for serial, usbtmc, and net drivers.
Now it should be obvious how to crash the server: connect a device to itself!
mydev spp -prog "device_c use_dev mydev"
TCL library
There is a TCL library Device2 for working with the server.
"New" interface:
-
Device2:addr
-- variable with the server address. When library is loading it is updated by runningdevice_c get_srv
and thus syncronized with device_c configuration file (TODO: what about -via setting?). -
Device2:get <action> <device> <msg> ...
-- the most general function for communicating with the server. All extra arguments are joined with<msg>
. -
Device2:ask <dev> <msg>
-
Device2:list
-
Device2:reload
-
Device2:close
-
Device2:ping
-
Device2:get_time
-
Device2:info <dev>
-
Device2:use <dev>
-
Device2:release <dev>
-
Device2:lock <dev>
-
Device2:unlock <dev>
-
Device2:log_start <dev>
-
Device2:log_finish <dev>
-
Device2:log_get <dev>
-- syntactic sugar for all actions
"Old" interface is almost compatable with Device library (https://github.com/slazav/tcl-device).
For each device itcl
object with cmd
, lock
, unlock
methods can be created. Methods
read
and write
are missing (they were not widely used and I want to get rid of them).
Device <name>
<name> cmd *IDN?
DeviceDelete <name>
For example, DeviceRole library can be switched to Device2 just by
replacing package use Device
by package use Device2
.
V.Zavjalov, 2020, slazav at altlinux dot org