Linux Agent User guide

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

Managing devices

By customizing Lua plugins scripts, the agent can support more features, such as configuration management and network parameters management.

Prerequisites

Required and optional packages

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.

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 in your environment, 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.

  1. 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
    
  2. Enter the directory and pull in all submodule dependencies.

    cd cumulocity-sdk-c
    git submodule init
    git submodule update
    
  3. 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
    
  4. Modify your init.mk file with the proper library name on the CPPFLAGS and LDLIBS 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 and pkg-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.

  5. 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.

Building the basic agent

This section explains how to build the Cumulocity IoT Linux agent without Modbus support.

  1. 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
    
  2. Export the SDK binaries and libraries path (that is, /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
    
  3. 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 .
    
  4. 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 and LDLIBS 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 and pkg-config --libs lua and confirm that no errors are returned.

  5. To build the agent in debug mode, run:

    make
    

    For production, to build in release mode, run:

    make release
    

Building the 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 have completed this step, continue with step 5 of Building the basic agent to build the agent.

Building the CANopen service

CANopen support is disabled by default. After you have completed 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 and more, 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.

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

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 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 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

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 (that is, can0). In this example, the simulator is automatically connected to the SocketCAN interface can0. Make sure that you have a proper can0 CAN interface, or use the default CANopen settings in the Cumulocity IoT Linux agent to have the agent create a vcan can0 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.

  1. 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
  1. 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 must 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