In this blog post, I present WebVCP - web-based user interfaces for Machinekit.
Reasons for web UIs over native UIs
I have dedicated a lot of my work in the last years ro QtQuickVcp which is a remote UI framework for Machinekit targeting desktop and mobile applications. So you may wonder why I even explored the possibilities of web UIs for Machinekit.
Here are my top reasons for exploring web front-ends for human-machine interfaces.
- Deployment: Deployment for web applications is evident. On the host you need to start a web server, on the client, you need a browser, done.
- QtQuick and OpenGL: Although this problem will resolve in a future version of Qt, it is annoying to not beeing able to run QtQuickVcp on the BeagleBone and other Embedded Linux device due to lack of sufficient graphic drivers.
- Rise in popularity: Web applications (not to confuse with web pages) are becoming more and more popular. The technology seems to mature and some applications such as draw.io can compete with native desktop software.
- Ease of use: I don't think that web apps are more intuitive than their desktop counterparts. However, the browser-workflow has become natural for most people and entering a URL in a web browser is something most people understand without special instructions.
I don't think that desktop and mobile applications will become obsolete shortly. However, I think that web applications are becoming healthy alternatives for the popular desktop front-end technologies.
For me, this was an interesting lecture since I discovered that web technologies seem to evolve in a parallel universe to desktop front-end technologies.
Some patterns are familiar, but most things work completely different to what I have worked with so far. If you are not already familiar with web development, stuff like Redux or intermorphic design can be very confusing.
Luckily I stumbled upon QmlWeb which brings QML, a declarative UI programming language, to the browser. That is perfect for me because I can solely focus on the backend and client-server communication.
From a developer perspective, QML is very similar to AngularJS 2. It uses components and property bindings, and the model-view approach is used to expose data models to the front-end.
The huge advantage for me is that I have worked with QML and QtQuick, the QML standard library, since the introduction by Nokia.
Machinetalk bindings for the browser
In fact, implementing the Node.js bindings was easy, since ZeroMQ, Protobuf and mDNS/DNS-SD bindings are all available. But I learned quickly that server-side bindings do not help be building a real-time Machinekit web-app. Building the complete client-server communication from the ground up was not what I was looking for.
So I decided that I need to learn more about web development before continuing with the project.
In fact, the solution I came up with is pretty similar to Michael Haberlers Webtalk. Webtalk is an application that converts Protobuf messages to JSON and ZeroMQ sockets to Websockets. Service discovery happens on the server side.
The WebVCP solution is very similar. However, instead of converting the messages to JSON I use Protobuf.js directly in the web browser. Moreover, I implemented the service discovery as REST API so that everything can be done from the client-side.
Below is a diagram that shows the function principle of WebVCP:
The message serialization works end-to-end from service to client without decoding the messages.
ZeroMQ provides internal capabilities For routing the messages to the correct destination. The combination of
XSUB sockets allows forwarding of subscription messages to the publisher. However, please note that this only works for bidirectional protocols such as
TCP. When a client subscribes to a particular destination the broker establishes a connection to the request address, if a connection is already open.
ROUTER-DEALER pattern works similar. The
ROUTER keeps track of the client connections and is, therefore able to route answers to message back to the sender. Note that we do not need to address clients directly from the service side, because the service is stateless.
Implementing a network protocol in specific language means implementing state machine and the relation to incoming and outgoing messages. As part of my Master's thesis, I created code generators to solve this problem in a platform independent way. The project is called Machinetalk GSL. Adding a new language or framework boils down to writing a new code generator.
Thanks to this approach it only required me to implement the Implementation Layer components. For implementing the WebVCP project this meant creating QmlWeb modules.
Example web app
I decided to reuse the Machinekit anddemo for the sample application. For the user interface, this means implementing two buttons and one LED-like indicator component.
Here is a video showing the functionality and syncing with QtQuickVcp and the HAL:
Although the example app is very simple it shows the syncing functionality of HAL remote. The UI itself does not contain any networking code. The QmlWeb HalRemote module does the service discovery, serialization, and message handling.
Long story short, this means creating reactive human-machine interfaces in the web browser without requiring deep knowledge of web development and network protocols.
In layman terms, this enables everyone with a text editor and a web browser to build reactive web apps for controlling machines.
The source code of WebVCP and can be found at GitHub.
Try it out
If can't wait to test it yourself, here are the install instructions:
First of all, you need a working Machinekit installation. I will not explain how to install Machinekit here. Please take a look at the Machinekit documentation for more information.
Additionally, you need a recent version of Node.js running on your Linux machine. On Debian you can use the following install commands:
curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash - sudo apt-get install -y nodejs
Next you need to clone and start the anddemo example:
git clone https://github.com/machinekoder/anddemo.git cd anddemo ./run.py & cd ..
At the moment, you also need to download and build my development branch of QmlWeb:
git clone https://github.com/machinekoder/qmlweb.git cd qmlweb git checkout origin/webvcp npm install npm run build cd ..
Next, you need to download and run WebVcp:
git clone https://github.com/machinekoder/webvcp.git cd webvcp npm install node index.js
Now it is time to open your web-browser enter the following URL:
localhost:3000. If all went well you should be able to see the anddemo web app.
The QmlWeb framework proofs useful for creating machine VCPs. Although QmlWeb is far from complete, it is already possible to create nice looking and reactive web applications with this technology.
In the long term, I hope this technology will lower the entry barrier to create web-based user interfaces for machines. Which hopefully will lead to better and graphically more powerful HMIs than what is currently the industry standard.
For me, this project serves anchor point into creating web applications. Although I have started my programming career with HTML4 and PHP, the world of web development got out of my control in the last years. Thanks to QmlWeb, web apps finally feel doable again.
I hope you have enjoyed reading this article and I'm looking forward to your feedback and ideas.