Overview
The Cumulocity IoT Linux agent is a generic device agent for connecting Linux-powered devices to Cumulocity IoT. It runs on all major Linux distributions like Ubuntu, Debian, Raspbian, and CentOS.
Supported functionality
Remote monitoring and control of industrial assets
- Modbus-TCP and Modbus-RTU
- CANopen (using a SocketCAN interface; requiring commercial library)
- Cloud Remote Access for remotely accessing assets via VNC, Telnet, or SSH protocols
Managing devices
- Periodically reporting memory usage and system load to Cumulocity IoT
- Sending log files (dmesg, syslog, journald, agent log) to Cumulocity IoT on demand
- Remotely executing commands via the device shell interface
By customizing Lua plugins scripts, the agent can support more features, such as configuration management and network parameters management.
Prerequisites
Required and optional packages
- Required packages
- A C++11-standard-compliant compiler
- liblua (>= 5.1)
- libcurl (>=7.57.0)
- Optional packages
- systemd (for auto-start of the agent on boot)
- libmodbus (>= 3.0.8), for the use of Modbus only
- lua-socket (>=3.0), for the use of CANopen only
The packages can be installed with the following commands in the terminal window on Ubuntu 18.04:
# compiler
sudo apt install build-essential
# required
sudo apt install liblua5.3-dev libcurl4-gnutls-dev
# optional for Modbus
sudo apt install libmodbus-dev lua-socket
# optional for CANopen
sudo apt install lua-socket
Info: The following steps have been tested for Ubuntu 18.04, but should work with other distributions as well.
Make sure that the following libraries (-dev version) are installed.
- libcurl >= 7.57.0
- lua >= 5.1
Confirm that the libraries are installed by using the apt
command (should show something like libcurl4-gnutls-dev or liblua5.3-dev).
apt list --installed | grep libcurl
apt list --installed | grep lua
In case they are not installed on your computer, search for the libraries' packages.
apt-cache search libcurl | grep dev
apt-cache search liblua | grep dev
Then, install the proper libraries. For example:
sudo apt install libcurl4-gnutls-dev
sudo apt install liblua5.3-dev
Building the C++ SDK
The agent software requires the Cumulocity IoT C++ SDK, so you need to build the Cumulocity IoT C++ SDK first, before starting to build the software.
-
Launch a Git client and clone the SDK repository to a directory of your choice. For example:
cd ~/<my_working_directory> git clone https://github.com/SoftwareAG/cumulocity-sdk-c.git
-
Enter the directory and pull in all submodule dependencies.
cd cumulocity-sdk-c git submodule init git submodule update
-
In the cumulocity-sdk-c directory, create an init.mk file by copying the common.mk file.
cp common.mk init.mk
Also, create a custom Makefile file by copying Makefile.template.
cp Makefile.template Makefile
-
Modify your init.mk file with the proper library name on the
CPPFLAGS
andLDLIBS
line. If you installed the liblua5.3-dev library then modify from:CPPFLAGS:=$(shell pkg-config --cflags libcurl lua) CXXFLAGS:=-Wall -pedantic -Wextra LDLIBS:=$(shell pkg-config --libs libcurl lua)
to:
CPPFLAGS:=$(shell pkg-config --cflags libcurl lua5.3) CXXFLAGS:=-Wall -pedantic -Wextra LDLIBS:=$(shell pkg-config --libs libcurl lua5.3)
Info: This step is required for the Ubuntu 18.04 LTS and Raspbian distributions. However, this step must be skipped for the CentOS 7 distribution. If you use other operating systems, run
pkg-config --cflags lua
andpkg-config --libs lua
and confirm that no errors are returned.If you don’t know which liblua version has already been installed on your device, you can find the version which you need to add to your init.mk by:
ldconfig -p | grep lua
It will return a name like “liblua5.3.so.0”, so you can assume that lua5.3 should be added.
-
To build the SDK in debug mode, run:
make
For production, to build in release mode, run:
make release
To remove all intermediate build files, run:
make clean
Building and installing the Cumulocity IoT Linux agent
Before getting started, make sure that you have compiled the Cumulocity IoT C++ SDK.
- For using the Cloud Remote Access feature, refer to Building the Cumulocity IoT Cloud Remote Access service.
- For using the Modbus support, make sure that you have the libmodbus and LuaSocket packages installed. Details on how to enable Modbus support are described in Building the agent with a Modbus support.
- For CANopen support, check if you have the CANopen library and SocketCAN connector commercially licensed by port industrial automation GmbH and the LuaSocket package installed. For details, refer to Building the Cumulocity IoT CANopen service.
Building the basic agent
This section explains how to build the Cumulocity IoT Linux agent without Modbus support.
-
Copy the Cumulocity IoT Linux agent repository to a directory of your choice.
cd ~/<my_working_directory> git clone https://github.com/SoftwareAG/cumulocity-agents-linux.git
-
Export the SDK binaries and libraries path (i.e. /home/me/repos/cumulocity-sdk-c). Preferably add the following code to your ~/.bashrc for permanence.
export C8Y_LIB_PATH=/path/to/cumulocity-sdk-c
-
Enter the cumulocity-agents-linux directory and copy the compiled binaries and libraries of the SDK. This is done by copying the bin and lib directories in the SDK to the cumulocity-agents-linux directory.
cd cumulocity-agents-linux cp -rP $C8Y_LIB_PATH/lib $C8Y_LIB_PATH/bin .
-
Customize your Makefile and correct the libraries names. If you installed the liblua5.3-dev library, modify lua to lua5.3 twice (in the
CPPFLAGS
andLDLIBS
lines)CPPFLAGS+=-I$(C8Y_LIB_PATH)/include $(shell pkg-config --cflags lua)\ -DPKG_DIR='"$(PKG_DIR)"' LDLIBS:=-lsera $(shell pkg-config --libs lua) -pthread
to
CPPFLAGS+=-I$(C8Y_LIB_PATH)/include $(shell pkg-config --cflags lua5.3)\ -DPKG_DIR='"$(PKG_DIR)"' LDLIBS:=-lsera $(shell pkg-config --libs lua5.3) -pthread
Info: This step is required for the Ubuntu 18.04 LTS and Raspbian distributions. However, this step must be skipped for the CentOS 7 distribution. If you use other operating systems, run
pkg-config --cflags lua
andpkg-config --libs lua
and confirm that no errors are returned. -
To build the agent in debug mode, run:
make
For production, to build in release mode, run:
make release
Building the Cumulocity IoT Cloud Remote Access service
The Cumulocity IoT Linux agent supports the Cloud Remote Access feature. If your device supports VNC, Telnet, or SSH remote access, you can remotely manage it via Cumulocity IoT. For details on the remote access functionality, refer to Cloud Remote Access.
To support the feature, you need to build the Cumulocity IoT Cloud Remote Access service aside from building the agent. To build it, run:
make vnc
Now you have an execution file vncproxy in cumulocity-agents-linux/bin.
The Cumulocity IoT Cloud Remote Access service needs no further configuration. It communicates with the Cumulocity IoT Linux agent via a local socket.
Building the agent with Modbus support
Modbus support is disabled by default. In between step 4 and step 5 of Building the basic agent, you need to do one additional step to enable it. The Modbus feature requires the libmodbus library, so make sure you have libdmobus installed before building the agent with Modbus support.
After step 4 of Building the basic agent, edit your Makefile file and set PLUGIN_MODBUS
to 1
(enabled). By default, this variable is set 0
(disabled).
PLUGIN_MODBUS:=1
After you finished this step, continue with step 5 of Building the basic agent to build the agent.
Building the Cumulocity IoT CANopen service
CANopen support is disabled by default. After you have finished all steps described in Building the basic agent, you need to do a couple of additional steps.
CANopen support is composed of two parts. One is a Lua plugin, which is included in the agent repository by default. However, to get actual CANopen support, you also need to build the Cumulocity IoT CANopen service, which is a C program based on the CANopen library and SocketCAN connector from port industrial automation GmbH.
The CANopen library and SocketCAN connector are commercially licensed by port industrial automation GmbH, and are not included in this repository. You need to get the CANopen library and the SocketCAN connector from port industrial automation GmbH if you want to build the Cumulocity IoT CANopen service.
Assume you have the CANopen library and SocketCAN connector available, you need to create a directory ext/port in the repository and extract the ZIP files there. After the extraction, your ext/port directory should have the following structure:
$ ls -hl ext/port/
drwxr-xr-x 1 tiens tiens 44 Nov 27 16:45 canopen
drwxr-xr-x 1 tiens tiens 80 Nov 27 16:45 drivers
$ ls -hl ext/port/canopen
-rw-r--r-- 1 tiens tiens 11K Nov 27 16:45 CHANGELOG
drwxr-xr-x 1 tiens tiens 664 Nov 27 16:45 include
drwxr-xr-x 1 tiens tiens 834 Nov 27 16:45 source
$ ls -hl ext/port/drivers
-rw-r--r-- 1 tiens tiens 21K Nov 27 16:45 CHANGELOG_DRV
drwxr-xr-x 1 tiens tiens 92 Nov 27 16:45 linux
-rw-r--r-- 1 tiens tiens 7.3K Nov 27 16:45 README
drwxr-xr-x 1 tiens tiens 206 Nov 27 16:45 shar_inc
drwxr-xr-x 1 tiens tiens 106 Nov 27 16:45 shar_src
To build the Cumulocity IoT CANopen service, move to the repository root directory and run:
cd canopen
make
Then the c8y_canopend execution file is created in cumulocity-agents-linux/bin.
The Cumulocity IoT CANopen service communicates with the Cumulocity IoT Linux agent via UDP port 9677. It gets all configuration, including SocketCAN interface, baud rate etc. automatically from the Cumulocity IoT Linux agent, so you just need to adjust all the CANopen settings in the Cumulocity IoT Linux agent configuration file (cumulocity-agent.conf) as described in the section Configuring the agent.
Installing the agent
Info: Before installing the agent, you need to configure the agent parameters in the cumulocity-agent.conf file. For details, refer to Configuring the agent.
You can install and uninstall the agent using the same commands regardless of whether your agent supports Modbus, CANopen or none of them. After you have built the agent, enter your cumulocity-agents-linux directory and run:
sudo make install
The agent’s binary files, the configuration file (cumulocity-agent.conf), the SmartREST template file (srtemplate.txt), the systemd service file, and the C++ SDK shared library files are now deployed to your device.
Uninstalling the agent
In your cumulocity-agents-linux directory, run:
sudo make uninstall
The agent binary files, the configuration file (cumulocity-agent.conf), the SmartREST template file (srtemplate.txt), the systemd service file, and the C++ SDK shared library files are now removed from your device.
Configuring the agent
The Cumulocity IoT Linux agent repository includes the cumulocity-agent.conf file. When you install the agent, the configuration file is deployed to /usr/share/cumulocity-agent/cumulocity-agent.conf by default. The agent reads this configuration file at startup. You can manually edit this file to adjust different parameters to suit your needs.
Device ID
A unique device ID is required to register your device. You can specify it using an “id” key. If not specified, the agent will use the device’s serial number recorded in the following paths to determine the device ID.
- /sys/devices/virtual/dmi/id/product_serial
- /proc/cpuinfo
- /sys/devices/virtual/dmi/id/product_uuid
- /sys/hypervisor/uuid
- /var/lib/dbus/machine-id
- /etc/machine-id
Parameter | Example value |
---|---|
id | id=myagent |
Server URL
The agent by default connects to the cumulocity.com instance. In case you’re using a different instance, you can change the server URL. The URL supports two protocol schemas. To use the HTTP version, set the URL to the format https://example.com. To use the MQTT version, set the URL to the format mqtts://example.com.
Parameter | Example value |
---|---|
server | server=https://mqtt.cumulocity.com or server=mqtts://mqtt.cumulocity.com |
Log settings
Parameter | Description | Example value |
---|---|---|
log.path | The file location for storing the agent’s logs | log.path=/var/log/cumulocity-agent.log |
log.level | Filter for lowest severity level to be enabled for logging. Available log severities are debug, info, notice, warning, error, and critical | log.level=debug |
log.quota | The maximum log file size before the log rotates, in KB | log.quota=8192 |
Plugins
Each feature is implemented as a Lua plugin.
Plugin | Description |
---|---|
system | Enables the agent to periodically report CPU and memory usage |
logview | Allows you to remotely view the device and the agent logs from Cumulocity IoT |
shell | Allows you to change all these parameters in the configuration file remotely from the device shell functionality from Cumulocity IoT |
version | Reports the agent version to Cumulocity IoT |
modbus | Implements the Cloud Fieldbus Modbus protocol |
canopen | Implements the Cloud Fieldbus CANopen protocol |
You can enable it by appending it to the lua.plugins parameter.
Parameter | Example value |
---|---|
lua.plugins | lua.plugins=system,logview,shell,canopen |
Agent measurements
These parameters define the interval for sending memory and CPU usage measurements, in seconds. The system plugin is required to activate the system configuration.
Parameter | Example value |
---|---|
system.mem.interval | system.mem.interval=300 |
system.cpu.interval | system.cpu.interval=300 |
Modbus configuration
You can change various Modbus parameters in the configuration file. The modbus plugin is required to activate the Modbus configuration.
Parameter | Description | Example value |
---|---|---|
modbus.transmitrate | The transmit rate for reporting measurements to Cumulocity IoT [in seconds] | |
modbus.pollingrate | The polling rate for querying the Modbus client for data [in seconds] | modbus.pollingrate=30 |
modbus.readonly | Controls the ability to write data to clients. 1 is read-only, 0 is writable | modbus.readonly=0 |
modbus.timeout.usec | The timeout interval used to wait for a response from a Modbus client [in microseconds] (from version 4.2.9 and onwards) | modbus.timeout.usec=5000000 |
Info: We recommend you to change the Modbus parameters via the Modbus Cloud Fieldbus UI.
Modbus-TCP configuration
Parameter | Description | Example value |
---|---|---|
modbus.tcp.port | The TCP port is used for Modbus-TCP. The default setting is 502 | modbus.tcp.port=502 |
Modbus-RTU configuration
Parameters | Description | Example values |
---|---|---|
modbus.serial.port | This is the type when your Modbus device is recognized as a serial interface by the Linux kernel, for example, /dev/ttyACM0. In this case, you also need to inform the agent about the serial port your device is mounted as: modbus.serial.port=/dev/ttyACM0 or modbus.serial.port=/dev/ttyUSB0 | modbus.serial.port=/dev/ttyACM0 |
modbus.serial.baud | The baud rate of the Modbus line, in kbit/s | modbus.serial.baud=19200 |
modbus.serial.databits | The data bits for Modbus-RTU | modbus.serial.databits=8 |
modbus.serial.parity | The parity. N, E or O | modbus.serial.parity=E |
modbus.serial.stopbits | The stopbits. 1 or 2 | modbus.serial.stopbits=1 |
CANopen configuration
You can change various CANopen parameters in the configuration file.
Parameters | Description | Example values |
---|---|---|
canopen.transmitRate | The transmit rate for measurement reporting [in seconds] | canopen.transmitRate=5 |
canopen.pollingRate | The polling rate for querying CANopen node for data [in seconds] | canopen.pollingRate=5 |
canopen.baud | The baud rate of the CAN line [in kbit/s] | canopen.baud=125 |
Info: We recommend you to change these CANopen parameters via the CANopen Cloud Fieldbus UI.
CANopen port
The default setting is the can0 interface. If you need to configure a different CAN interface, for example, can1, edit this parameter.
Parameters | Example values |
---|---|
canopen.port | canopen.port=can1 |
CANopen interface type
The agent supports three different CAN interface types:
Parameter | Example value | Description |
---|---|---|
canopen.type | canopen.type=can | This is the type when your CAN device is supported by the socketCAN driver and automatically appears as a network CAN interface. |
canopen.type | canopen.type=vcan | This is the default type. It uses the virtual CAN interface from the Linux kernel, which is mainly for testing and demo purposes. |
canopen.type | canopen.type=slcan | This is the type when your CAN device is recognized as a serial interface by the Linux kernel, for example, /dev/ttyACM0. In this case, you also need to inform the agent about the serial port your device is mounted as: canopen.serial=/dev/ttyACM0 or canopen.serial=/dev/ttyUSB0 |
Starting the agent process and other services
- To start the Cumulocity IoT Linux Agent with or without Modbus support, you need to follow the steps in Starting the agent process.
- To start the Cumulocity IoT Cloud Remote Access service, refer to Starting the Cumulocity IoT Cloud Remote Access service.
- To start the Cumulocity IoT CANopen service and CANopen device simulator, refer to Starting the Cumulocity IoT CANopen service.
Starting the agent process
In your cumulocity-agents-linux directory, run:
sudo cumulocity-agent
However, the agent process stops when the agent crashes. To improve this, there is an alternative way for Linux distributions with systemd:
sudo systemctl enable cumulocity-agent
sudo systemctl start cumulocity-agent
This way, the agent automatically restarts by a watchdog process in case it crashes.
Starting the Cumulocity IoT Cloud Remote Access service
Make sure that you have the vncproxy file in the cumulocity-agents-linux/bin directory. If this is not the case, refer to the section Building the agent with Cloud Remote Access service.
In your cumulocity-agents-linux directory, run:
sudo vncproxy
Alternatively, you can use systemd. Make sure you have the vncproxy file in the /usr/bin directory. If this is not the case, install the agent first.
Copy the service script to /lib/systemd/system, then enable and start the service.
sed 's#$PREFIX#/usr#g' utils/cumulocity-remoteaccess.service > /lib/systemd/system/cumulocity-remoteaccess.service
sudo systemctl enable cumulocity-remoteaccess
sudo systemctl start cumulocity-remoteaccess
Starting the Cumulocity IoT CANopen service
Make sure that you have the c8y_canopend file in the cumulocity-agents-linux/bin directory. If this is not the case, refer to the section Building the agent with CANopen service first.
In your cumulocity-agents-linux directory, run:
./bin/c8y_canopend
Cumulocity IoT CANopen simulator
There is also a CANopen simulator included in the repository for testing purposes. To build and run it, execute:
cd tools/canopen_simulator
make
./c8y_canopen_simulator 5 0
Info: 5 is the CANopen node ID that you want the simulator to run with, and 0 is the CAN interface number, i.e.
can0
. In this example, the simulator is automatically connected to the SocketCAN interfacecan0
. Make sure that you have a propercan0
CAN interface, or use the default CANopen settings in the Cumulocity IoT Linux agent to have the agent create a vcancan0
interface for you.
Building packages
This repository includes RPM, Debian, and Snappy package building scripts.
RPM
After building the agent, run:
sudo make rpm args='-r 1.1' # replace 1.1 with required rpm release number
You might need to edit the cumulocity-agents-linux/pkg/rpm/build_rpm.sh file to adjust package dependencies.
To include the Cloud Remote Access feature, use cumulocity-agents-linux/pkg/rpm/build_rpm_remoteaccess.sh instead.
Debian
After building the agent, run:
make debian
You might need to edit the cumulocity-agents-linux/pkg/debian/DEBIAN/control file to adjust Architecture
to your target machine’s architecture and Depends
to the packages you are using.
To include the Modbus feature, add your libmodbus library to the Depends:
field of the cumulocity-agents-linux/pkg/debian/DEBIAN/control file.
To include the Cloud Remote Access feature, use cumulocity-agents-linux/pkg/debian/DEBIAN-remoteaccess/ instead of the default cumulocity-agents-linux/pkg/debian/DEBIAN/. In addition, modify the debian:
field of your Makefile with the following steps.
- Add
$(BIN_DIR)/$(VNC_BIN)
to the line in which you copy the binaries to a staging directory. The line will look like:
@cp $(BIN_DIR)/$(BIN) $(BIN_DIR)/srwatchdogd $(BIN_DIR)/$(VNC_BIN) $(STAGE_DIR)/$@$(PREFIX)/bin
- Add the following line after the line in which you copy utils/cumulocity-agent.service.
@sed 's#$$PREFIX#$(PREFIX)#g' utils/cumulocity-remoteaccess.service > $(STAGE_DIR)/$@/lib/systemd/system/cumulocity-remoteaccess.service
Snappy
The requirements are the same as above, but the build requires special treatment because Ubuntu Snap Core uses its own file system structure. Instead, run:
make release PREFIX=/snap/cumulocity-agent/current/usr DATAPATH=/var/snap/cumulocity-agent/common
make snap PREFIX=/snap/cumulocity-agent/current/usr DATAPATH=/var/snap/cumulocity-agent/common
This will create the snap package. Then the agent needs to be installed in developer mode, since snap sandboxing is currently too restrictive. To install it, run:
sudo snap install <agent.snap> --devmode
The agent starts automatically after installation and every time the machine boots.
Info: Packaging requires version 2.10 of snapcraft or higher because lower versions do not support the confinement property, which is required for packaging the agent as a snap.
To include the Modbus feature, add your libmodbus library to the Depends:
field of cumulocity-agents-linux/pkg/snapcraft.yaml.
To include the CANopen feature, first build the CANopen service. After that, overwrite the content of cumulocity-agents-linux/pkg/snapcraft_canopen.yaml to the default cumulocity-agents-linux/pkg/snapcraft.yaml. In addition, modify the snap:
field of your Makefile. Add $(BIN_DIR)/c8y_canopend
to the line in which you copy the binaries to a staging directory. The line will look like:
@cp $(BIN_DIR)/$(BIN) $(BIN_DIR)/srwatchdogd $(BIN_DIR)/c8y_canopend $(STAGE_DIR)/$@/bin
Make sure the first two lines of /lua/canopen.lua refer to your Lua version. By default,
package.path = package.path .. ';/snap/cumulocity-agent/current/usr/share/lua/5.2/?.lua'
package.cpath = package.cpath .. ';/snap/cumulocity-agent/current/usr/lib/x86_64-linux-gnu/lua/5.2/?.so'
If you built the agent with Lua 5.3, you have to change 5.2
to 5.3
.
To include the Cloud Remote Access feature, first build the Cloud Remote Access service. After that, overwrite the content of cumulocity-agents-linux/pkg/snapcraft_remoteaccess.yaml to the default cumulocity-agents-linux/pkg/snapcraft.yaml. In addition, modify the snap:
field of your Makefile. Add a $(BIN_DIR)/$(VNC_BIN)
to the line in which you copy the binaries to a staging directory. The line will look like:
@cp $(BIN_DIR)/$(BIN) $(BIN_DIR)/srwatchdogd $(BIN_DIR)/$(VNC_BIN) $(STAGE_DIR)/$@/bin