Background
EPICS is a well-known framework for controlling a wide range of hardware. Just like other inventions from the particle physicists, it reaches beyond the field of the particle physics experiments.
Scenario
EPICS provides a comprehensive bucket of tools for almost all use cases. In the age of the internet, however, many unprecedented demands have emerged. One of which is to allow remote control over the internet.
Here comes a trivial problem that has never been addressed before: how to communicate as a web front with the EPICS IOCs?
Technical Consideration
As a never-before new system, one of the most fundamental engineering principles is to stick with the existing standards as much as possible. Based on this principle, 3 sub-principles must be followed.
- use loosely-coupled microservices each provides a limited and well-defined functionality
- communication protocols and data structure are kept simple and consistent across the smallest necessary scope.
- use standardized protocols, deployment workflow, and libraries
Hence a bridge between IOCs of the 20th century and the web frameworks of the 21st century is necessary.
Design
Data Flow
The data flow is the foundation of any software system and should be drafted before the actual development.
Communication Protocol
According to the basic structure, the proxy needs to handle 2 types of protocols: one for the microservices and one for the IOCs. The former has many standards I can choose from. The latter only has two standards at the moment: CA and PV.
As PV is only available to EPICS 7+, for better compatibility of the proxy, CA should be supported first.
Considering that caget
caput
are compatible with the stateless protocols, but camonitor
requires a stateful protocol like WebSocket, the protocol to the microservices must support both cases. Hence the most popular communication protocol HTTP-based REST is not an option. After a quick research, GraphQL from Facebook is found to satisfy all the demands.
Framework
Both CA and GraphQL are too complicated to make from scratch. Therefore some existing frameworks must be utilized. Based on the choice of the protocols, 2 frameworks are required:
- a GraphQL server
- a CA library
The most popular GraphQL server is the apollo-server, and it is the only server that supports real-time subscriptions out of the box.
The only CA library comes from EPICS-base, in the form of dynamic libraries and executable binaries.
Implementation
The development of the proxy was not smooth and simple, therefore I will divide this section into challenges.
Feasibility
The very first question is: is such proxy even possible?
This question can be broken down into 2:
- is it possible to integrate CA library with GraphQL server?
- is the proxy able to communicate with the IOCs on the other hosts in the network?
The first question is answered by this tool and this tool. Thanks to the great pioneers who made these tools!
The second question can be cleared by a simple test using the tools mentioned above.
Setup Apollo Server
GraphQL is way more complicated than it sounds if you are new to it. There are many useful resources out there to help newbies set up their first server. I found this and this to be very helpful.
The biggest challenge here is to understand the concept of the resolver. It is a standardized component of GraphQL so many different packages can work together without a problem. As I use TypeScript to code, type-graphql suits my needs best. Although a code-first GraphQL server is better, the Apollo server does not support the code-first approach.
Having implemented caget
, caput
and camonitor
as Query
, Mutation
and Subscription
respectively, the server part is done.
Connect to IOC
Here comes the most tricky part. As Apollo Server only runs with Node.js, using JS/TS is the only choice. However, node-epics is too old to support the latest Node.js. Hence I made my own fork. Sadly it depends on ref-napi
which only works on node before 13. Therefore it requires node <13, which puts this proxy to the same restriction. Luckily we have containers that minimize the impact of such restriction.
After some head-scratching, this tool is published. The connection to the IOC is easily implemented and tested.
This issue took me a week before the first version is published whereas the other issues only took me a couple of days.
Deployment
As the proxy relies on a specific version of the Node, it is better shipped with the Node of the correct version. Hence docker is the best solution.
Personally I use Kubernetes to manage the containers. I recommend anyone who needs docker to consider to switch to Kubernetes as it is just awesome.
Links
click here for the proxy
click here for the JS binding of CA
Top comments (0)