This article is part of a series with the name IoT Remote Power Switch – Project Part 8.
It describes the design and implementation of a web client application on an embedded computer.
Web Clients vs Web Servers
Web clients on embedded computers are more and more in demand. They are a far superior solution over web servers on embedded computers for various reasons:
- Embedded computers often lack the hardware resources for a decent web server. Often they are very slow and lead to a bad user experience.
- Introducing a web server on an embedded computer adds a lot of complexity to the application.
- Web servers require frequent security patches. With thousands of devices in the filed, that can become very tedious.
- Web servers require content updates since they are directly responsible for the user experience. For the afore mentioned reason, this can be a tedious task.
- Embedded computers work behind firewalls. Opening port 80 introduces considerable security risks to the IT environment.
- Mitigating such risks by the means of VPN tunnels or other measures introduce more overall system complexity and costs.
For this project, the design and implementation of the embedded application shall be as simple as possible. It shall require little proprietary technology know how or tools, neither for the hardware nor for the software development. The knowhow that is required shall be easily obtainable in the Internet.
Tasks of the Embedded Application
- Read the desired status of the switch from the web server periodically.
- Update the digital output that controls the power switch periodically, according to the input from the last step.
- Write the actual status of the switch to the web server periodically.
- Take the URI of the web server as command line argument on application start.
Design of the Embedded Application
Below is a software component diagram that illustrates the design of the application.
The modules follow the layer pattern. The information flow is top down: higher layers make use of lower layers through their API, but lower layers are unaware of their higher layers. All modules are executed periodically. The main cycle time is 1 second.
Following a short description of the functionality of the modules:
The top layer. It makes use of the prpWebClient, prpSwitch and the drvSysTick modules. It starts all modules at program start, stops all modules at program end, and passes the data between the modules. It does this inside the main() function.
This module issues the GET and POST requests to the web server and passes the data forth and back to the application.
- OS Sockets and Network Interface
These two pseudo modules are transparent to the software. (Pseudo because they don’t exist in reality, but only in the software model.) The sockets are hidden (and handled) by the prpWebClient module, the network interface is abstracted by the operating system.
This module abstracts the power switch. It provides a getter and setter method to set its state (OFF or ON).
This module abstracts the GPIO hardware. It doesn’t exist in this version of the application, since I intend to develop and test it initially on my Ubuntu system, which doesn’t provide digital outputs.
- GPIO Interface
This is the hardware interface. Again, it doesn’t exist yet. It will come in place once the software runs on an embedded computer.
This module generates the system tick. The system tick is used to time the main loop of the application. The module depends on timer functions of the operating system.
- OS Timers
This pseudo module provides the necessary timer functions to the system tick module.
- Timer Hardware
This is the timer hardware on the target system. It generates timing information with micro-second resolution.
The naming convention stems from Bitcontrol’s company internal naming convention; we apply it to our C/C++ embedded applications. app stands for application, prp for data preparation and drv for driver. GPIO stands for general purpose inputs and outputs.
Since I am familiar with Eclipse CDT on Linux, the decision is quickly made. It’s my choice for this application. I can also use it later for porting the application to an embedded computer.
I downloaded Eclipse’s Kepler version a while ago. It will do the job for this simple app, but any earlier or later version should work also.
Another decision I have to make is: C or C++? I know both languages well. I choose C. Remember: one of the goals is to keep the application as simple as possible. Eclipse CDT supports both native C and C++ applications.
And last but not least: the application needs a library that implements a web client. The choice is vast. I’m going to use the cURL library, also named curl. It’s been for long on the market and can also be used inside a Linux bash shell once it’s installed.
Since my Ubuntu 14 installation is quite clever, I don’t bother with downloading and installing the library from the web. I simply type
curl-config (got that command from a web page some time ago) and get the instructions what to do from the operating system. Since openssl sounds attractive for communication with https servers, I decide to install libcurl4-openssl-dev.
$> curl-config The program 'curl-config' can be found in the following packages: * libcurl4-gnutls-dev * libcurl4-nss-dev * libcurl4-openssl-dev Try: sudo apt-get install $> sudo apt-get install libcurl4-openssl-dev [sudo] password for andreas: Reading package lists... Done Building dependency tree Reading state information... Done The following extra packages will be installed: libgcrypt11-dev libgnutls-dev libgnutlsxx27 libgpg-error-dev libidn11-dev libldap2-dev libp11-kit-dev librtmp-dev libtasn1-6-dev Suggested packages: libcurl4-doc libcurl3-dbg libgcrypt11-doc gnutls26-doc gnutls-bin The following NEW packages will be installed: libcurl4-openssl-dev libgcrypt11-dev libgnutls-dev libgnutlsxx27 libgpg-error-dev libidn11-dev libldap2-dev libp11-kit-dev librtmp-dev libtasn1-6-dev 0 upgraded, 10 newly installed, 0 to remove and 6 not upgraded. Need to get 2'212 kB of archives. After this operation, 9'123 kB of additional disk space will be used. Do you want to continue? [Y/n] :
Later, the application will build against the curl library. For this purpose, the linker will need to know the path and name of the curl library.
curl-config --libs outputs
-L/usr/lib/x86_64-linux-gnu -lcurl. The Eclipse installation already knows about the linux-gnu library. All I have to add to the projectis the curl library in the project configuration. (Note: the -l has to be omitted in the entry; it’s the linker flag for library.)
For details on the implementation please look at the source code. It can be found here (pre-release v0.6). I’ve copied the few required Bitcontrol library modules into the project’s source folder for easy access and use.
The embedded application’s project folder is an Eclipse CDT project. You can import it to your Eclipse installation. It should build and run immediately.
For testing the embedded application, I start the local node.js web server and open a browser with the URL of the web server. In my case it’s
http://localhost:9000/index.html. I start the embedded application with the command line argument
http://localhost:9000/. For now it has the hard coded device identifier 1.
Setting the Device Identifier field to 1 and clicking on the OFF or ON buttons respectively should change the displayed Status accordingly. If you are having problems, check the output of the web server on the console, the output of the embedded application on the console, and you can use Google’s Postman to issue commands against the web server.
Summary and Outlook
That’s the main part of the embedded application. I’ll have to port it to the embedded computer and add the digital input/output driver module.
As usual, you find the source code here; it’s pre-release v0.6. Note that the
node_modules folder isn’t part of the repository. After downloading the repo or its zip file you’ll have to change directory to the top-level folder of the project and run
$> npm install.
I am over the hill! What’s left is the software port to the embedded computer, selecting and buying a digitally controllable 230VAC power switch and testing the complete setup in the lab.
Then I can deploy the web server to the could, the remote power switch (embedded computer, power switch and electric heater) to my remote workshop and control it from my mobile phone.