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.
These reasons were enough for me to start learning JavaScript, Node.js, Express, AngularJS, React and much more at Code School.
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.
QmlWeb
QmlWeb is an approach for creating web applications with QML. QML is a declarative programming language introduced by the Qt project to design highly custom user interfaces.
QML works together with JavaScript as imperative language. Qt uses it's own JavaScript engine for parsing and running QML applications. So it seems only logical to use the JavaScript engine of a modern web browser to run QML applications.
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.
QmlWeb is far from complete. However, many of the design patterns and ideas from QtQuickVcp are easily portable to JavaScript. In fact, the goal is that QtQuickVcp and WebVCP applications even can share the same source code.
Machinetalk bindings for the browser
One particular thing that was holding me back so far is that there was no browser JavaScript binding for Machinetalk. However, I already started working on Node.js bindings earlier this year.
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 XPUB
and 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.
ZeroMQs 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.
Conclusion
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.
Your
Machine Koder
Comments 2
Great appreciation your nice posts.
I'm also interesting with a thinking about using the Jupyter notebook server (in PC or Machinekit side) + ipywidgets or pyqt to interactive with Machinekit which can be used for send real-time output data and monitor the response results to the browser application.
I am not really sure the relations about all technology terms. I just like the data visualization concept with Jupyter and google can't find someone do such things with Machinekit.
Author
Thank you, Hori.
Jupyter looks very interesting. You should be able to combine the Jupyter web application with WebVCP to monitor signals in real-time.
If you are interested solely in the visualization part of Jupyter you should also take a look at the [Qt Charts](http://doc.qt.io/qt-5/qtcharts-index.html) and [Qwt](http://qwt.sourceforge.net/).
--
Machine Koder