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.
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?
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.
The data flow is the foundation of any software system and should be drafted before the actual development.
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.
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.
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.
The development of the proxy was not smooth and simple, therefore I will divide this section into challenges.
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 second question can be cleared by a simple test using the tools mentioned above.
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.
Subscription respectively, the server part is done.
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.
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.