Client Application¶
The client application (devmgrClient) is a simple utility allowing to send commands to the Device Manager from the command line. In this context we use the words commands and events as synonyms.
The devmgrClient uses the interface module modif
(generated from a protobuf definition) to compose the payload of the messages. The
devmgrClient sends the messages using the API from rad
for request/reply (implemented with ZeroMQ).
$ devmgrClient [<timeout>] [<node>] [<port>] <command> ["<parameters>"]
Where
<timeout> reply timeout in msec, default=5000
<node> optional node or ip address, default=localhost
<port> optional port, default=5555
<command> command to be sent to the server (e.g. modif.ReqInit)
<parameters> optional parameters of the command.
List of Commands¶
The commands (events) currently supported by the devmgrClient utility are:
Command | Parameters |
---|---|
modif.ReqInit | “” |
modif.ReqEnable | “” |
modif.ReqDisable | “” |
modif.ReqState | “” |
modif.ReqStatus | “” |
modif.ReqSetup | <JSON filename> |
modif.ReqRecover | “” |
modif.ReqReset | “” |
modif.ReqConfig | “” |
modif.ReqSetLog | “<ERROR|INFO|DEBUG|TRACE>” |
modif.ReqSimulate | “<device id1>, … ,[<device idn>]” |
modif.ReqStopSim | “<device id1>, … ,[<device idn>]” |
modif.ReqIgnore | “<device id1>, … ,[<device idn>]” |
modif.ReqStopIgn | “<device id1>, … ,[<device idn>]” |
modif.ReqBeginAcq | “<filename prefix>, <data product id>” |
modif.ReqEndAcq | “” |
modif.ReqExit | “” |
Examples¶
Note
The following examples assume the server is listening for incoming events under port 5577 in the local host.
Enabling debug level in the server¶
$ devmgrClient 5000 localhost 5577 modif.ReqSetLog "DEBUG"
Initialising the server¶
$ devmgrClient 5000 localhost 5577 modif.ReqInit ""
Moving the server to Operational state¶
$ devmgrClient 5000 localhost 5577 modif.ReqEnable ""
Executing a Setup command from the command line¶
In order to send a setup command to the Device Manager it is needed to define the parameters and action associated in a file using the JSON format. The content of this file will be converted to a protobuf message by the devmgrClient
utility.
$ devmgrClient 50000 localhost 5577 modif.ReqSetup "<JSON file>"
An example of the JSON file is include below. This JSON files specifies to named position OFF for device motor1
{ "fcs": [
{
"id": "ins1.fcs1",
"motor": [
{
"id": "motor1",
"name": "OFF",
"action": "MOVE_BY_NAME"
}
]
}
]
}
Another example of a JSON file for setting up more than one device:
{ "fcs": [
{
"id": "ins1.fcs1",
"shutter": [
{
"id": "shutter1",
"action": "OPEN"
}
],
"shutter": [
{
"id": "shutter2",
"action": "OPEN"
}
],
"shutter": [
{
"id": "shutter3",
"action": "OPEN"
}
]
}
]
}
Python Interface¶
It is possible to communicate with the Device Manager through clients developed in Python. The RAD provides the services that encapsulate the ZeroMQ messages and using the generated Protocol Buffer the library from the modif module, developers can create client applications that serialize and send messages to the server.
Note
The following Python example creates a message to open the shutter. It uses asyncio and zmq packages that are part of the ELT DevEnv.
import sys
import argparse
import logging
import asyncio
import signal
import concurrent
from functools import partial
import zmq.asyncio
# ICS RAD packages
from rad.core.run import run_with_cleanup
from rad.services.msg import MsgRequestor
from rad.services.msg import MsgReplier
# ICS FCF Interface Module
from devmgr.modif.requests_pb2 import *
zmq.asyncio.install()
loop = asyncio.get_event_loop()
zmq_ctx = zmq.asyncio.Context()
"""
RAD class that manages the ZMQ ELT message. Endpoint need to be
adapted to the correct one.
"""
requestor = MsgRequestor(endpoint = 'tcp://localhost:7577',
zmq_ctx = zmq_ctx,
loop = loop)
queue = asyncio.Queue(loop=loop)
"""
Defines a co-routine for opening the shutter
"""
async def open_shutter(loop, requestor):
req = ReqSetup()
fcs = req.fcs.add()
fcs.id = "ins1.fcs1"
shutter1 = fcs.shutter.add()
shutter1.id = "shutter1"
shutter1.action = Shutter.ActionShutter.Value('OPEN')
fut = requestor.send(req)
# Wait until it gets the reply
rep = await asyncio.wait_for(requestor.receive(RepSetup), timeout=3)
"""Runs the co-rotine inside the event loop"""
run_with_cleanup(open_shutter (loop, requestor),
loop=loop, cleanup_timeout=5.0)